17

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

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

出力:

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

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

この関連性を見つけました

4

3 に答える 3

17

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

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


実際の問題に直交するのsizeof(char)1定義上であるため、コードから削除することは理にかなっています。

于 2011-12-08T20:10:35.987 に答える
9

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. 文字列リテラルには、暗黙のヌル ターミネータが含まれます。あなたは言いたかった:

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

利点として、strcat は最初の nul 文字で停止するため、この場合は問題ありません。

于 2011-12-08T20:11:56.090 に答える
0

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

する必要があります

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

すべきではありませんか?文字列の長さの計算が間違っています。

于 2011-12-08T20:12:04.327 に答える