-2

重複の可能性:
malloc()とfree()はどのように機能しますか?

奇妙な問題が発生しましたが、なぜそれが機能しないのかよくわかりません。

Xcodeには次のコードがあります。

void *ptr = malloc(1024 * 1024 * 100);
memset(ptr, 0, 1024 * 1024 * 100);
free (ptr); //trace this line
ptr = malloc (1024 * 1024 * 100);
memset(ptr, 0, 1024 * 1024 * 100);
free (ptr); //trace this line

free()行のそれぞれにブレークポイントを設定しましたが、プログラムをトレースしたとき、freeは実際には100MBを解放しませんでした。ただし、数値を100から500に変更すると(500mbを2回割り当てる)、memset 500mb、free()は正常に機能します。なんで?

4

4 に答える 4

2

free不適切なアドレスで呼び出す場合を除い て、失敗することはありません(戻り値はありません)。これにより、未定義の動作が発生します。

free実際にメモリを解放するかどうかを気にする必要はありませんfree。動的なメモリ使用量が終了した後、正しいアドレスを呼び出すようにする必要があります。残りはコンパイラが処理します。
これは、コンパイラが正しく処理できると信じるべきことの1つです。

また、 (名前が示すように)再利用のためfreeに割り当て解除されたメモリを解放するようにマークするだけです。割り当て解除されているメモリをゼロにしたり初期化したりすることはありません。

于 2013-01-22T15:42:08.783 に答える
0

他の人がすでに言ったfree()ように、OSにメモリを戻す必要はありません。しかし、私はあなたがメモリが返されるかどうかを決して気にしないべきであるという考えを拒否します。気にするのには十分な理由があるはずですが、正当な理由があります

メモリをOSに戻したい場合は、次の保証を提供するプラットフォーム固有の方法を使用してください。

  1. mmapそれをMAP_ANONYMOUSサポートするシステム上で(多くありますが、MAP_ANONYMOUSPOSIXではありません):mmapの代わりにmalloc、のmunmap代わりにfree

  2. VirtualAllocおよびVirtualFreeWindowsの場合。

[他のシステムのためにここに何かを追加する必要がありますか?お気軽にご提案ください。]

メモリを割り当てるこれらの方法は、大きなメモリユニット(システムページサイズ以上)で機能します。

于 2013-01-22T16:00:38.040 に答える
0

free()以前にバックアップしたページのマッピングをすぐに解除してOSに戻す必要はありませんが、バッファは割り当てられていません。それはあなたが再びメモリを素早く割り当てることができるようにそれらを維持するかもしれません。プログラムが終了すると、ページのマッピングが解除され、OSに返されます。

于 2013-01-22T15:46:25.450 に答える
0

メモリのブロックをに渡す場合free、そのメモリは必ずしもすぐにオペレーティングシステムに戻されるとは限りません。実際、C標準の表現に基づいて、プログラムが終了するまでメモリをOSに戻すことができないと主張する人もいます。

問題の文言は(C99、§7.20.3.2/ 2)です。「free関数を使用すると、ptrが指すスペースの割り当てが解除されます。つまり、さらに割り当てられるようになります。」彼らの主張は、メモリのブロックが割り当てられてから解放された場合、それは再び割り当て可能になるはずですが、OSに戻された場合、他のプロセスがそれを取得する可能性があるため、それ以上の割り当てには使用できなくなります、標準が要求するように。個人的には、その議論が完全に説得力があるとは思いませんが(「別のプロセスによって割り当てられた」というのはまだ割り当てだと思います)、それは人生です。

ほとんどのライブラリは、OSからメモリの大きなチャンクを割り当ててから、それらの大きなチャンクの一部をプログラムにサブ割り当てします。プログラムによってメモリが解放されたら、そのメモリブロックを「使用可能な」リストに入れてさらに割り当てます。ほとんどの場合(少なくとも時々)、空きブロックのリストをウォークスルーし、隣接するアドレスである空きブロックをマージします。

また、多くの人は、解放された後に保持するメモリについていくつかのヒューリスティックに従います。まず、そのブロック内のメモリのいずれかが使用されている限り、ブロック全体を保持します。ただし、ブロック内のすべてのメモリが解放されている場合は、そのサイズと、(多くの場合)使用可能な空きメモリの量を確認します。使用可能な量や空きブロックのサイズがあるしきい値を超えると、通常はOSに解放されます。

しきい値を固定するのではなく、(たとえば)固定サイズではなく使用可能なメモリのパーセンテージに基づいてしきい値を設定することにより、環境に合わせて動作を調整しようとするものもあります。それがなければ、利用可能なメモリが通常はるかに小さい10年前に作成されたプログラムは、多くの場合、かなりの「スラッシング」を実行します。つまり、同じ(または同様の)サイズのブロックをOSとの間で繰り返し割り当てたり解放したりします。

于 2013-01-22T18:18:28.540 に答える