4

したがって、ヒープに 256 ブロックを割り当てました。

char* ptr1 = malloc(128);
char* ptr2 = malloc(128);

現在ヒープの上にあると想定しているptr2を解放した後、プログラムブレーク(ヒープの現在の場所)は減少しません。ただし、別の malloc を実行すると、malloc によって返されるアドレスは、解放されたアドレスと同じになります。

だから私は次の質問があります:

ブロックを解放しても、プログラム ブレークが減らないのはなぜですか? free を呼び出すと、正確には何が起こりますか?次に malloc を宣言したときにアドレスが同じになるように、解放されたメモリをどのように追跡しますか?

4

5 に答える 5

4

不特定の動作です。1つの特定のプラットフォーム/OS/コンパイラ/libcの組み合わせだけを気にしない限り、単一の答えに頼ることはできません。OSを指定しておらず、C標準では特定の実装が記述されていないか、必要ありません。C99から(私はまだC11の最終公開バージョンを持っていません):

7.20.3

calloc、malloc、およびrealloc関数への連続した呼び出しによって割り当てられるストレージの順序と隣接性は指定されていません。割り当てが成功した場合に返されるポインタは、任意のタイプのオブジェクトへのポインタに割り当てられ、割り当てられたスペース内のそのようなオブジェクトまたはそのようなオブジェクトの配列にアクセスするために使用できるように適切に配置されます(スペースが明示的に割り当て解除されるまで) 。割り当てられたオブジェクトの存続期間は、割り当てから割り当て解除まで延長されます。そのような各割り当ては、他のオブジェクトから互いに素なオ​​ブジェクトへのポインタを生成するものとします。返されたポインタは、割り当てられたスペースの開始(最下位バイトアドレス)を指します。スペースを割り当てることができない場合は、ヌルポインターが返されます。要求されたスペースのサイズがゼロの場合、動作は実装定義です。nullポインターが返されるか、

于 2013-03-22T02:49:02.300 に答える
2

GNU libcのこのマニュアルは、役に立つかもしれません。

ここに要点があります

場合によっては、freeは実際にメモリをオペレーティングシステムに戻し、プロセスを小さくすることができます。通常、実行できるのは、後でmallocを呼び出してスペースを再利用できるようにすることだけです。その間、スペースは、mallocによって内部的に使用されるフリーリストの一部としてプログラムに残ります。

于 2013-03-22T02:47:25.387 に答える
0

ブロックを解放しても、プログラム ブレークが減らないのはなぜですか?

そのメモリはすでにプログラムに与えられているため、減少しないと思います。

私が電話するとfree()、正確には何が起こりますか?

メモリのそのセクションは割り当て可能としてマークされ、以前の内容を上書きできます。

この例を考えてみましょう...

[allocatedStatus][sideOfAllocation][allocatedMemory]
                                   ^-- Returned pointer

これを考慮すると、はを false にfree()マークできるため、今後のヒープへの割り当てでそのメモリを使用できます。[allocatedStatus]

free()次回アドレスを宣言するときに 同じアドレスになるように、どのように d メモリを追跡しmalloc()ますか?

私はそうは思わない。空きメモリをスキャンしたところ、空きとしてマークされていた前のブロックが見つかりました。

于 2013-03-22T02:19:00.170 に答える
0

以下は、メモリ アロケータがどのように機能するかを大まかに示したものです。

空きメモリ ブロックのリンクされたリストである「ビン」(「空きリスト」) の束を持つアロケータがあります。各ビンには異なるブロック サイズが関連付けられています (つまり、8 バイト ブロック、16 バイト ブロック、32 バイト ブロックなどのリストを持つことができます。7 または 10 バイト ブロックのような任意のサイズでも構いません)。プログラムが (通常は malloc() を介して) メモリを要求すると、アロケータはデータに適合する最小のビンに移動し、その中に空きメモリ ブロックがあるかどうかを確認します。そうでない場合は、OS からいくらかのメモリ (通常はページと呼ばれます) を要求し、取得したブロックを小さなブロックの束に切り取り、ビンを埋めます。次に、これらの空きブロックの 1 つをプログラムに返します。

free を呼び出すと、アロケータがそのメモリ アドレスを取得し、元のビン (別名フリー リスト) に戻します。:)

メモリはまだ使用できるので、ページング メモリを保持する必要はありませんが、プログラムに関しては無料です。

于 2013-03-22T02:30:08.660 に答える
0

free() を呼び出すと、それは完全にオペレーティング システム次第だと思います。オペレーティング システムは、そのメモリをすぐに再利用するか、気にせず、後でそのメモリ セグメントを取得可能としてマークするかを選択できます (おそらく同じことです)。私の知る限り、メモリ(重要な場合)は、Windowsで free() の直後にタスクマネージャーで利用可能として表示されます。

ここで話しているメモリはvirtualであることに注意してください。つまり、オペレーティング システムは必要なことを何でも伝えることができ、マシンの物理的な状態を正確に表していない可能性があります。

OS を作成している場合、メモリ割り当てをどのように管理するかを考えてみてください。おそらく、リソースを浪費する可能性のある急いで何かをしたくないでしょう。ここでは 128 バイトについて話しているのですが、それだけで貴重な処理時間を無駄にしたいですか? それがその行動の理由であるかどうかにかかわらず、少なくとももっともらしい. ループでそれを実行してから、別のループで free() を実行するか、メモリの大きなチャンクを割り当てて、何が起こるかを確認し、実験してください。

于 2013-03-22T02:27:04.253 に答える