C - realloc()関数 - データが壊れることを証明する

この単純なコードで私が見つけたものを見てください:

#include 
#include 
#include 

char *string;

int main(){    

string = (char *) malloc(50*sizeof(char));
strcpy(string, "initi1l wording cont2ining forty-nine ch3r4cters.");
printf("BEFORE: %s\n", string);
string = (char *) realloc(string, 24*sizeof(char));
printf("AFTER: %s\n", string);

system("PAUSE");

return 0;
}

outpoutは次のとおりです。

BEFORE: initi1l wording cont2ining forty-nine ch3r4cters.
AFTER: initi1l wording cont2inia

文字列の最後に 'a'があることに注目してください。私はどこから来ているのか分かりません。たぶんヒープのどこかにあります。元のデータブロックからのものではありません。最初は構造体の配列にrealloc()を使用していましたが、明らかにデータをより重要な形で破損していました。

この問題を回避するにはどうすればよいですか?

3
まあ、おそらく疑いはありませんが、答えは明らかです:reallocは壊れていません。
追加された 著者 Per Johansson,
私は質問を見つけることができませんでした。
追加された 著者 Mob,
さて、後で、私が問題を回避する方法を聞いてみるかもしれません、aixの応答に対する私の応答を見てください。
追加された 著者 Mike mmm,

4 答え

C strings require a NUL terminator. You're implicitly expecting realloc() to somehow figure out that the memory contains a C string, and replace its last character with NUL. It doesn't do this; you have to do it yourself:

string = (char *) realloc(string, 24*sizeof(char));
string[23] = 0;  //<========= THE FIX
printf("AFTER: %s\n", string);

つまり、コード内のバグです。

10
追加された
そうですね。ありがとう、それを指摘してください...しかし、私は小さなブロックに構造体の配列を縮小していたときに私は終わりの最後の要素を期待していた(とNULLの終端文字を提供する必要はなかった)。起こったのは完全な汚職だった。
追加された 著者 Mike mmm,

それはありません! Cでは "文字列"は \ 0で区切られた文字セットです。この場合、 "string"を印刷しようとすると、ランダムな\ 0がメモリ内に見つかるまで、オリジナルの24文字とテールが得られます

5
追加された
reallocを使用してサイズを増やすと、古いコンテンツの背後にある部分には、標準で指定されているように不定バイトが含まれます。サイズを小さくするために使用すると、新しいサイズのメモリはプログラムの任意のランダムなメモリ位置になります。何かが含まれている可能性があります。アクセスは無効です。実際に何が起こったのか(この場合、他の実装は異なる動作をするかもしれません)は、reallocが最初の数バイトを上書きして空きメモリとしてマークすることです。
追加された 著者 Daniel Fischer,
大丈夫。ありがとう。私は、reallocがどのようにランダムなデータを配列の配列に追加しているかを証明できるときに戻ってきます。 (私は文字列の例でNULLを忘れていたことに同意します)。
追加された 著者 Mike mmm,

Cの文字列はNULLで終了します。私はプログラムがクラッシュしなかったことに驚いています。

2
追加された
それはなぜでしょうか?割り当てられたブロックの後に、例えば、次のブロックのサイズが存在する可能性があります。これは、短い場合、上位バイトがゼロになります;-)
追加された 著者 Michael Krelin - hacker,
クールな観察。
追加された 著者 Mike mmm,

それはキャラクター25で、最初の24で0終了はありません。

1
追加された