Cメモリ割り当て関数のほとんどの実装は、インラインまたは個別に、各ブロックのアカウンティング情報を格納します。
典型的な方法の1つ(インライン)は、要求されたヘッダーとメモリの両方を実際に割り当て、最小サイズにパディングします。たとえば、20バイトを要求した場合、システムは48バイトのブロックを割り当てることがあります。
- サイズ、特殊マーカー、チェックサム、次/前のブロックへのポインターなどを含む16バイトのヘッダー。
- 32バイトのデータ領域(20バイトは16の倍数に埋め込まれます)。
次に与えられるアドレスは、データ領域のアドレスです。次に、ブロックを解放free
すると、指定したアドレスを取得し、そのアドレスまたはその周りのメモリを詰めていないことを前提として、その直前のアカウンティング情報を確認します。グラフィカルに、それは次のようになります。
____ The allocated block ____
/ \
+--------+--------------------+
| Header | Your data area ... |
+--------+--------------------+
^
|
+-- The address you are given
ヘッダーとパディングのサイズは完全に実装によって定義されることに注意してください(実際には、全体が実装によって定義されます(a)が、インラインアカウンティングオプションは一般的なものです)。
アカウンティング情報に存在するチェックサムと特別なマーカーは、「メモリアリーナの破損」や「2回解放」などのエラーの原因となることがよくあります。
パディング(割り当てをより効率的にするため)は、要求されたスペースの終わりを少し超えて問題を引き起こすことなく書き込むことができる理由です(ただし、それを行わないでください。これは未定義の動作であり、場合によっては機能するため、それはそれを行うことは大丈夫だという意味です)。
(a)malloc
組み込みシステムでの実装を記述しましたが、128バイト以下(システムで最大の構造のサイズ)を要求したとしても、128バイトを要求したとしても、128バイトが得られます(それ以上要求すると、 NULLの戻り値で満たされる)。非常に単純なビットマスク(つまり、インラインではない)を使用して、128バイトのチャンクを割り当てるかどうかを決定しました。
私が開発した他のものには、16バイトチャンク、64バイトチャンク、256バイトチャンク、および1Kチャンク用の異なるプールがあり、ビットマスクを使用して、どのブロックが使用または利用可能かを決定しました。
これらの両方のオプションは、会計情報のオーバーヘッドを削減するとの速度増加するために管理malloc
し、free
私たちが働いていた環境で特に重要なのは、(解放する際に隣接するブロックを合体する必要はありませんが)。