2011-07-25 35 views
2

我用这个方法来编码对象的C的base64字符串,但该应用有时坠毁:为什么这个Objective-C代码会引发一个malloc错误?

- (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[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

    //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); 

你知道是什么导致了这里的崩溃?

+3

你应该启用Guard Malloc(alt + cmd + R,tab“Diagnostics”,选中“Enable Guard Malloc”)来查看你是否有缓冲区溢出。 – zneak

+0

简单的激光:为什么?因为它含有大量的语法糖! –

回答

5

也许这就是问题所在:你分配outLength

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

在第一行字节,但在第二行中,你写入一个超出结尾的字节的位置缓冲。根据页面边界和malloc内部的其他神秘事件,这可能是好的,也可能不会。这将解释为什么它不会每时间崩溃

试试这个:

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

这可能会解决你的问题。

+0

认识到了这个问题,非常感谢Benzado – Chris

3

您修改过去的malloc分配OutputBuffer中结束与:

outputBuffer[outLength] = 0; 

如果outLength是3,那么你可以设置outputBuffer[0]outputBuffer[1]outputBuffer[2]但不outputBuffer[3]

要么改变你的malloc到:

char *outputBuffer = malloc(outLength+1); 

或更改您的初始化:

outputBuffer[outLength-1] = 0; 
+0

你不想使用'outputBuffer [outLength-1]',因为'outLength'是计算出来的,我们可能需要在字符串中写入很多。 – benzado

+0

除非你在前面的语句中增加outLength以允许它,但即使你不这样做,它也会比改变malloc'd块之外的内存更好。它可能不会给你你想要的答案,但它不会崩溃! – LavaSlider

+0

非常感谢Lavaslider,您的解决方案也是对的! – Chris

相关问题