2011-07-25 50 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

相關問題