3

このコードを実行すると:

#include <stdio.h>

typedef struct _Food
{
    char          name [128];
} Food;

int
main (int argc, char **argv)
{
    Food  *food;

food = (Food*) malloc (sizeof (Food));
snprintf (food->name, 128, "%s", "Corn");

free (food);

printf ("%d\n", sizeof *food);
printf ("%s\n", food->name);
}

私はまだ得ます

128
Corn

私は食べ物を解放しましたが。どうしてこれなの?メモリは本当に解放されていますか?

4

7 に答える 7

10

あなたが「食べ物」を解放するとき、あなたはあなたがそれで終わったと言っています。ただし、ポインタフードは同じアドレスを指し、そのデータはまだそこにあります(必要のないときに解放されるメモリのすべてのビットをゼロにする必要があるのはオーバーヘッドが大きすぎるでしょう)

基本的に、これが機能するのは非常に小さな例だからです。freeステートメントとprintステートメントの間に他のmalloc呼び出しがあった場合、これが表示されない可能性があり、ひどい方法でクラッシュする可能性があります。この動作に依存するべきではありません。

于 2010-06-02T17:40:52.810 に答える
3

無料の食べ物のようなものはありません:)何かを「解放」すると、同じスペースが再び他の人によって使用される準備ができていることを意味します。ゴミでいっぱいにするという意味ではありません。第二に、ポインタ値は変更されていません。真剣にコーディングしている場合は、このような潜在的なジャンクアクセスが発生しないように、ポインタを解放したらNULLに設定する必要があります。

于 2010-06-02T17:44:04.377 に答える
2

sizeofはコンパイル時の操作であるため、メモリ割り当てによって動作が変わることはありません。

freeメモリを消去せず、ブロックを未使用としてマークするだけです。数百メガバイトのメモリを割り当てても、ポインタが上書きされない場合があります(最新のコンピュータには大量のRAMが搭載されています)。ただし、メモリを解放すると、その値に依存できなくなります。

開発環境にメモリ割り当てのデバッグ設定があるかどうかを確認します。ブロックを上書きする設定がある0xDEADBEEF場合もfreeあります。

NULLまた、呼び出し直後にポインタを設定する習慣を身に付けることもできますfree(プログラムが早期に大音量でクラッシュするように促すため)。

于 2010-06-02T17:46:44.807 に答える
2

メモリを解放しても、必ずしもその内容が上書きされるわけではありません。

于 2010-06-02T17:37:26.483 に答える
1

freeそのメモリブロックを再利用できることをメモリアロケータに通知します。ブロックをゼロなどで上書きすることはありません。幸いなことに、これは非常にコストのかかる操作になる可能性があるためです。それ行うことは、ポインタのそれ以上の逆参照を未定義にすることですが、「未定義」の動作は、「以前と同じことを行う」ことを非常によく意味します-あなたはそれに頼ることができません。別のコンパイラ、別のrunime、または他の条件下では、例外がスローされたり、プログラムが終了したり、他のデータが破損したりする可能性があるため、実行しないでください。

于 2010-06-02T17:48:00.347 に答える
1

Cには、「構造体にデータがある」や「構造体にデータがない」などのことはありません。プログラムには、メモリ内のどこかを指すポインタがあります。このメモリがアプリケーションに属している(つまり、システムに戻されていない)限り、常に何かが含まれます。その「何か」は完全なゴミかもしれませんし、多かれ少なかれ意味があるように見えるかもしれません。さらに、メモリには、意味のあるものとして表示されるガベージが含まれている可能性があります(以前にそこに保存されていたデータの残り)。

これはまさにあなたが実験で観察したことです。構造体の割り当てを解除すると、以前は構造体が占めていたメモリに正式にガベージが含まれます。ただし、そのガベージは、割り当てが解除された時点でその構造体オブジェクトに格納されていた元のデータの断片に似ている可能性があります。あなたの場合、あなたは幸運だったので、データは無傷に見えます。ただし、それを当てにしないでください。次回は完全に破壊される可能性があります。

C言語に関する限り、あなたがしていることは未定義の振る舞いを構成します。割り当て解除された構造体に「データがある」かどうかを確認することはできません。あなたが尋ねている「なぜ」の質問は、C言語の領域には実際には存在しません。

于 2010-06-02T17:50:08.090 に答える
0

一部のシステムでは、メモリを解放するとアドレススペースからメモリがマップ解除され、割り当てを解除した後でアクセスしようとすると、コアダンプまたは同等のものが取得されます。

win32システム(少なくともXPまで)では、これは特に当てはまりません。Microsoftは、32ビットWindowsでメモリサブシステムを作成し、メモリを解放した後にメモリを使用するよく知られたMS-DOSアプリケーションとの互換性を維持するために、意図的にメモリブロックを残しました。

MS-DOSプログラミングモデルにはマッピングやプロセススペースの概念がないため、これらのタイプのバグは、Windows95でDOSモードプログラムとして実行されるまで、プログラムの失敗として表示されませんでした。

この動作は、32ビットWindowsで10年以上持続しました。Vistaや7などのシステムでレガシー互換性が廃止されているため、変更される可能性があります。

于 2010-06-02T17:45:02.927 に答える