2011-07-25 15 views
2

Iは、オブジェクト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、タブ「診断」、「Guard Mallocを有効にする」にチェックマークを付ける)を有効にする必要があります。 – zneak

+0

簡単なアンサー:なぜですか?文法的に砂糖が多いのはCだから! –

答えて

5

あなたが outLengthを割り当てる最初の行で
char *outputBuffer = malloc(outLength); 
outputBuffer[outLength] = 0; 

char *outputBuffer = malloc(outLength+1); 

以上にあなたの初期設定を変更します2番目の行では、その行の最後から1バイト先に書き込みます。バッファ。 mallocのページの境界やその他の不思議な出来事によっては、それは問題ないかもしれません。それはなぜ毎時時間をクラッシュさせないか説明するでしょう。

は、代わりにこれを試してください:あなたの問題を解決する可能性がある

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

を。

+0

問題を認識しました、ありがとう – Chris

3

あなたはとあなたのmallocさ出力バッファの終わりを越え変更:outLengthが3であれば、あなたはoutputBuffer[3]outputBuffer[0]outputBuffer[1]、およびoutputBuffer[2]を設定することはできませんが

outputBuffer[outLength] = 0; 

のいずれかにあなたのmalloc関数を変更:たぶん、これが問題である

outputBuffer[outLength-1] = 0; 
+0

'outLength'が計算されるので、あなたは' outputBuffer [outLength-1] 'を使いたくないので、それを文字列に多く書く必要があります。 – benzado

+0

前のステートメントでそれを可能にするためにoutLengthを増やさない限り、そうでない場合でも、mallocされたブロックの外側のメモリを変更するよりもはるかに良いでしょう。それはあなたが望む答えを与えるかもしれないが、それはクラッシュしないだろう! – LavaSlider

+0

ありがとう、Lavaslider、あなたの解決策も正しかった! – Chris

関連する問題