开发者

Why does this Objective-C code raise a malloc error?

开发者 https://www.devze.com 2023-03-22 10:40 出处:网络
I used this method to encode base64 string in object-c, but the app was crashed sometimes: - (NSString *) base64Encode

I used this method to encode base64 string in object-c, but the app was crashed sometimes:

- (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[o开发者_JS百科utLength-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;

}

The error is :

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

and when I debug, it stop in this line:

free(outputBuffer); 

Do you know what caused crash here ?


Maybe this is the problem:

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

In the first line you allocate outLength bytes, but in the second line you write to a position one byte beyond the end of the buffer. Depending on page boundaries and other mysterious happenings inside malloc, that might be OK or it might not. That would explain why it doesn't crash every time.

Try this instead:

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

That might fix your problem.


You modify past the end of your malloc'd outputBuffer with:

outputBuffer[outLength] = 0;

If outLength is 3, then you can set outputBuffer[0], outputBuffer[1], and outputBuffer[2] but not outputBuffer[3].

Either change your malloc to:

char *outputBuffer = malloc(outLength+1);

Or change your initialization to:

outputBuffer[outLength-1] = 0;
0

精彩评论

暂无评论...
验证码 换一张
取 消