3

次のコードセグメントでは、の後free(x)に、なぜy0になるのですか?

x私の理解によると、によってポイントされていて、まだによってポイントされているヒープ内のメモリは、y他の誰かに割り当てられていません。では、どのようにして0に変更できますか?

free(x)また、 0に変更したのではないと思います。

コメントはありますか?

#include <stdio.h>

int main(int argc, char *argv[])
{
    int *y = NULL;
    int *x = NULL;

    x = malloc(4);
    *x = 5;

    y = x;
    printf("[%d]\n", *y); //prints 5

    free(x);

    printf("[%d]\n", *y); //why doesn't print 5?, prints 0 instead

    return 0;
}
4

4 に答える 4

12

これは未定義の動作であり、説明は推測にすぎません。

C ライブラリのデバッグ バージョンを実行している可能性があり、デバッグ バージョンの free() は指定された領域をゼロにするのではないかと推測できます。

于 2010-04-01T07:22:21.443 に答える
4

で何が行われるfreeかは、実装によって異なります。解放後にメモリをゼロにすることは禁止されていません。

そして、あなたがしているのは未定義の動作です。

于 2010-04-01T07:21:51.927 に答える
2

行の後にyがxと同じアドレスを指していないか

y = x;

xを解放すると、 yが指すメモリも解放されます。

なぜ '0' が出力されるのか疑問に思っている場合、その未定義の動作ですが、一部のプログラマーが解放された領域を '0' に設定するという慣行を以前に見たことがあります。

「Binky the pointer fun video」というこのビデオをダウンロードしてください(これは冗談ではなく、実際には非常に教育的です)。

于 2010-04-01T07:27:08.753 に答える
2

への呼び出しfree()は、によって割り当てられたメモリ ブロックをmalloc()、C ランタイムがヒープ用に維持するデータ構造 (この場合は「フリー リスト」と呼ばれるもの) に戻します。

ヒープ データ構造を操作すると、指し示しているものが偶発的に変更される可能性がありますy(プログラムはもうメモリを所有していないため、メモリが変更されるべきではないと信じる理由はありません)。

プログラムの非デバッグ ビルドでは、ランタイムは通常、解放されたメモリを無効にするために特に何もしませんが、前述したように、独自の簿記の結果として変更を加える可能性があります (ただし、メモリは属していないため)。呼び出し元にはもう、ランタイムは好きなことをすることができます)。

デバッグ ビルドでは、問題をより容易に特定できる問題が発生することを期待してプログラムがメモリを使用する場合、ランタイムはメモリを無効である可能性が高い値に明示的に上書きする可能性があります。通常、解放されたメモリ ブロックを上書きするために使用される値はゼロではありません。これは、ゼロが原因でバグが発生しないことが多いためです (つまり、NULL ポインター チェックにより、コードが無効なメモリ アクセスを「処理」します)。たとえば、MSVC のデバッグ ヒープ マネージャーは、解放されたメモリを値 0xDD で上書きします (詳細については、OS がメモリを malloc/free/new/delete で 0xCD、0xDD などに初期化するタイミングと理由を参照してください)。

于 2010-04-01T07:31:35.830 に答える