皆さんこんにちは、
free(pointer) を定義すると、OS はどのくらいのサイズを解放する必要があるかを知るようになります。つまり、 size は提供せず、free ステートメントへのポインターのみを提供します。サイズを内部でどのように処理しますか?
ありがとう、ニール
皆さんこんにちは、
free(pointer) を定義すると、OS はどのくらいのサイズを解放する必要があるかを知るようになります。つまり、 size は提供せず、free ステートメントへのポインターのみを提供します。サイズを内部でどのように処理しますか?
ありがとう、ニール
free はシステム コールではないため、OS には手がかりがありません。ただし、C ライブラリのメモリ割り当てシステムは、メモリが最初に malloc() によって割り当てられたときに何らかの方法でサイズを記録しているため、解放する量を認識しています。
mallocを呼び出すと、Cライブラリがヒープ上にスペースを自動的に切り分けます。ヒープ上に作成されたものは動的に作成されるため、特定の時点でヒープ上にあるものは、スタックの場合とは異なります。したがって、ライブラリは、ヒープに割り当てたすべてのメモリを追跡します。
ある時点で、ヒープは次のようになります。
p---+
V
---------------------------------------
... | used (4) | used (10) | used (8) | ...
---------------------------------------
ライブラリは、各ブロックに割り当てられているメモリの量を追跡します。この場合、ポインタpは中央のブロックの先頭を指します。
次の呼び出しを行う場合:
free(p);
そうすれば、ライブラリはヒープ上でこのスペースを解放します...
p---+
V
----------------------------------------
... | used (4) | unused(10) | used (8) | ...
----------------------------------------
さて、次にスペースを探しているときは、次のような電話で言います。
void* ptr = malloc(10);
新しく使用されなかったスペースがプログラムに再度割り当てられる可能性があります。これにより、プログラムが使用するメモリの総量を減らすことができます。
ptr---+
V
----------------------------------------
... | used (4) | used(10) | used (8) | ...
----------------------------------------
ライブラリがサイズの内部管理を処理する方法は異なります。これを実装する簡単な方法は、各ブロックのサイズを保持するために割り当てられた各ブロックの先頭にバイト数を追加することです(例では1と言います)。したがって、以前のヒープメモリのブロックは次のようになります。
bytes: 1 4 1 10 1 8
--------------------------------
... |4| used |10| used |8| used | ...
--------------------------------
^
+---ptr
ここで、ブロックサイズが2で割り切れるように切り上げられると言うと、サイズの最後に余分なビットがあります(これは、常に0と見なすことができるため、これを使用して、対応するブロックが使用または未使用です。
ポインタを無料で渡すと:
free(ptr);
ライブラリは、指定されたポインタを1バイト戻し、使用済み/未使用ビットを未使用に変更します。この特定のケースでは、ブロックを解放するために実際にブロックのサイズを知る必要はありません。同じ量のデータを再割り当てしようとした場合にのみ問題になります。次に、malloc呼び出しがダウンし、次のブロックが空いているかどうかを確認します。それが空いている場合、それが適切なサイズである場合、そのブロックはユーザーに返されます。そうでない場合、新しいブロックがヒープの最後でカットされ、必要に応じてOSからより多くのスペースが割り当てられます。
サイズはアロケーターの内部に格納され、free に渡すポインターを使用してそのデータに到達します。非常に基本的なアプローチは、ポインターの前にサイズ 4 バイトを格納することです。そのため、ポインターから 4 を引くと、そのサイズへのポインターが得られます。
OS はこれを直接処理しないことに注意してください。C/C++ ランタイム アロケーターによって実装されます。