Почему этот код Objective C вызывает ошибку malloc? - PullRequest
2 голосов
/ 25 июля 2011

Я использовал этот метод для кодирования строки base64 в object-c, но приложение иногда зависало:

- (NSString *) base64Encode
{
    //Point to start of the data and set buffer sizes
    int inLength = [self length];
    int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0);
    const char *inputBuffer = [self bytes];
    char *outputBuffer = malloc(outLength);
    outputBuffer[outLength] = 0;

    //64 digit code
    static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    //start the count
    int cycle = 0;
    int inpos = 0;
    int outpos = 0;
    char temp;

    //Pad the last to bytes, the outbuffer must always be a multiple of 4
    outputBuffer[outLength-1] = '=';
    outputBuffer[outLength-2] = '=';

    /* http://en.wikipedia.org/wiki/Base64
     Text content   M           a           n
     ASCII          77          97          110
     8 Bit pattern  01001101    01100001    01101110

     6 Bit pattern  010011  010110  000101  101110
     Index          19      22      5       46
     Base64-encoded T       W       F       u
     */

    while (inpos < inLength){
        switch (cycle) {
            case 0:
                outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2];
                cycle = 1;
                break;
            case 1:
                temp = (inputBuffer[inpos++]&0x03)<<4;
                outputBuffer[outpos] = Encode[temp];
                cycle = 2;
                break;
            case 2:
                outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4];
                temp = (inputBuffer[inpos++]&0x0F)<<2;
                outputBuffer[outpos] = Encode[temp];
                cycle = 3;                  
                break;
            case 3:
                outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6];
                cycle = 4;
                break;
            case 4:
                outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f];
                cycle = 0;
                break;                          
            default:
                cycle = 0;
                break;
        }
    }
    NSString *pictemp = [NSString stringWithUTF8String:outputBuffer];
    free(outputBuffer); 
    return pictemp;

}

Ошибка:

malloc: *** error for object 0x164084: incorrect checksum for freed object - object was probably modified after being freed.

и когда я отлаживаю, он останавливается в этой строке:

free(outputBuffer); 

Знаете ли вы, что вызвало сбой здесь?

Ответы [ 2 ]

5 голосов
/ 25 июля 2011

Может быть, это проблема:

char *outputBuffer = malloc(outLength);
outputBuffer[outLength] = 0;

В первой строке вы выделяете outLength байтов, но во второй строке вы записываете позицию на один байт за концом буфера. В зависимости от границ страницы и других загадочных событий внутри malloc это может быть нормально, а может и нет. Это объясняет, почему он не падает каждый раз.

Попробуйте вместо этого:

char *outputBuffer = malloc(outLength + 1);
outputBuffer[outLength] = 0;

Это может решить вашу проблему.

3 голосов
/ 25 июля 2011

Вы изменяете после конца вашего malloc'd outputBuffer с помощью:

outputBuffer[outLength] = 0;

Если outLength равен 3, тогда вы можете установить outputBuffer[0], outputBuffer[1] и outputBuffer[2], но не outputBuffer[3].

Либо измените ваш malloc на:

char *outputBuffer = malloc(outLength+1);

, либо измените инициализацию на:

outputBuffer[outLength-1] = 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...