メモリアロケーターの書き込み
cのメモリアロケーターのスニペット
メモリアロケーター101-シンプルなメモリアロケーターを書きます
void * malloc ( size_t size );
void free ( void * ptr );
Block * merge_blocks ( Block * block );
// the above three will be implemented first later calloc and realloc データ構造を定義します。各ブロックのサイズと割り当てステータスを追跡するためにデータ構造が必要です。これは、サイズの単純な構造体であり、ブロックが自由かどうかを示すフラグである可能性があります。
ヒープの初期化:プログラムが開始されたら、ヒープとして機能するためにメモリの塊を確保する必要があります。これはmmap()システムコールを使用して実行できます。
malloc()を実装する:この関数は、リクエストを満たすのに十分な大きさのフリーブロックを見つける必要があります。そのようなブロックが存在しない場合、ヒープのサイズが増加するはずです。適切なブロックが見つかったら、割り当てられたときにマークされ、そのアドレスが返されます。
free()を実装する:この関数は、メモリのブロックへのポインターを取り、それをフリーとしてマークし、解放されたブロックが最後にある場合はヒープのサイズを潜在的に縮小する必要があります。
realloc()を実装する:この関数は、割り当てられたブロックをサイズ変更する必要があります。これには、新しいブロックを見つけて古いデータをコピーすることが含まれる場合があります。
断片化を処理する:時間が経つにつれて、ヒープは、全体に散らばっているフリーブロックで断片化することができます。隣接するフリーブロックを合体するなど、ヒープを解体するための戦略を実装することをお勧めします。
ヒープアロケーターのコンテキストでは、「ブロック」はヒープ内のメモリの塊を指します。これがあなたがそれらを必要とする理由とそれらがどのように機能するかです:
なぜブロックするのですか? :メモリを管理している場合、管理可能なチャンク、または「ブロック」に分割すると役立ちます。各ブロックは、独立して割り当てて扱うことができます。これにより、メモリを効率的に使用できます。必要なだけメモリを割り当てることができ、それ以上のメモリを割り当てることができます。
ブロック構造:各ブロックには通常、ブロック(そのサイズや自由または割り当てられているかどうかなど)とブロックに保存されている実際のデータに関するメタデータが含まれます。メタデータは、メモリを管理するためにアロケーターによって使用されます。
割り当て: malloc()を呼び出すと、アロケーターは要求された量のデータを保持するのに十分な大きさのフリーブロックを探します。見つけた場合、そのブロックが割り当てられたときにそのブロックをマークし、ブロックのデータ部分へのポインターを返します。
取引: free()を呼び出すと、アロケーターはブロックをfreeとしてマークし、将来の割り当てに利用できるようにします。解放されたブロックがヒープの端にある場合、アロケーターはヒープのサイズを減らしてメモリを解放する可能性があります。
断片化:時間が経つにつれて、ブロックが割り当てられ、扱われると、ヒープが断片化される可能性があります。これは、自由メモリが小さな紛争のない小さなブロックに分割されることを意味します。これにより、十分なフリーメモリがある場合でも、 malloc()呼び出しに十分な大きさのブロックを見つけるのが難しくなります。これを処理するために、アロケーターは多くの場合、隣接するフリーブロックを合体するなど、ヒープをデフラインするロジックを含みます。