web-dev-qa-db-ja.com

realloc():char *にstrcatのスペースを作るために再割り当てするときの次のサイズが無効

次のコードで無効なメモリエラーが発生します。

printf(" %s\n","FINE 5");
printf("%s LENGTH IS: %d\n","FINE 6",strlen(": "));
buffer = (char *)realloc(buffer, strlen(buffer)* sizeof(char) + (strlen(": ")+1)* sizeof(char));
printf(" %s\n","FINE 7");
strcat(buffer, ": \0");

出力:

ファイン5
FINE 6 LENGTH IS:2
* glibcが検出されました*./auto:realloc():無効な次のサイズ:0x08cd72e0 *** =======バックトレース:========= /lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x6dd591]

ここで注意すべき点はFine 7は印刷されません。すべての実行で無効な次のサイズのエラーが同じ場所にあります。

見つかった this 関連

13
PUG

このエラーは、コードの他の一部がヒープを破損しているために発生します。残りのコードを確認しないと、そのエラーが何であるかはわかりません。

_FINE 7_が出力されないという事実は、reallocが失敗していることを示しています。そして、その失敗は、実行の早い段階でのヒープの破損が原因でbufferが無効になるためであるに違いありません。


実際の問題に直交するsizeof(char)は、定義により_1_なので、コードから削除するのが理にかなっています。

12
David Heffernan

David Heffernanが指摘しているように、根本的な問題は、ヒープを破壊するコードの他の場所でのワイルドポインターである必要があります。

ただし、このコードの抜粋には、検討する価値のある他のいくつかの事項があります。

  1. Sizeof(char)は定義により1であるため、新しいサイズ式ではsizeof(char)は不要です。

  2. Reallocからの戻り値を、再割り当てしているバッファーへの唯一のポインターに直接割り当てないでください。エラーでreallocがNULLを返す場合、古いバッファへのポインタが失われ、独自のメモリリークが発生します。あなたはいつも以下の適切な同等物をしたいです:

    footype *p = realloc(oldbuff, newsize);
    if (!p) {
        handle_error();
    } else {
        oldbuff = p;
    }
    
  3. Cでは、void *は代入時に自動的に正しい型に変換され、キャストする必要はありません。さらに、キャストすることで、問題の関数の宣言を含めるのを忘れたときに、役立つエラーメッセージが表示されない場合があります。

  4. 文字列リテラルには暗黙のNULターミネーターが含まれます。あなたは言いたかった:

    strcat(バッファ、 ":");

上側では、strcatは最初のnul文字で停止するため、この場合は害はありません。

8
Greg Jandl

(char *)realloc(buffer, strlen(buffer)* sizeof(char) + (strlen(": ")+1)* sizeof(char));

する必要があります

(char *)realloc(buffer, (strlen(buffer) + strlen(": ") + 1) * sizeof(char));

すべきではありませんか?あなたは文字列の長さが間違っているので数学です。

0
Grambot