C では、動的メモリ管理は、特にパフォーマンスが重要なアプリケーションにおいて効率的なソフトウェアを開発する上で重要な側面です。標準ライブラリの malloc() や free() などの関数は一般的に使用されますが、頻繁に呼び出される場合には断片化や割り当て時間の低下などのオーバーヘッドと制限が伴います。これらの問題に対する 1 つの解決策は、メモリ プール アロケータ を作成することです。
このブログでは、単純なメモリ プール アロケータを C で最初から作成する方法を説明します。メモリ プールを使用すると、大きなメモリ ブロックを事前に割り当てて手動で管理し、断片化を減らしメモリを向上させることができます。割り当てパフォーマンス。
メモリ プール アロケータ は、大きなメモリ ブロックが事前に割り当てられ、必要に応じてその小さなチャンクがプログラムに割り当てられるカスタム メモリ管理戦略です。メモリが不要になると、再利用のためにプールに戻されます。このアプローチにより、malloc() と free() を直接使用するよりも高速な割り当てと割り当て解除が可能になり、メモリ使用率も向上します。
基本的なメモリ プールの仕組みは次のとおりです:
まず、メモリ プールとその中のブロックの単純な構造を定義します。各ブロックには空きリスト内の次のブロックへのポインターがあり、これによりメモリの割り当てと解放を迅速に行うことができます。
#include <stdio.h> #include <stdlib.h> #include <stddef.h> #define POOL_SIZE 1024 // Total memory pool size // Define a block structure with a pointer to the next free block typedef struct Block { struct Block *next; } Block; // Define the MemoryPool structure typedef struct { Block *freeList; unsigned char pool[POOL_SIZE]; // Pre-allocated pool } MemoryPool;
このコード内:
メモリプールを初期化するには、プールをブロックに分割し、空きリストを設定する必要があります。各ブロックは次の空きブロックを指す必要があります。
void initMemoryPool(MemoryPool *pool) { pool->freeList = (Block *)pool->pool; Block *current = pool->freeList; // Create a free list of blocks for (int i = 0; i < (POOL_SIZE / sizeof(Block)) - 1; i++) { current->next = (Block *)((unsigned char *)current + sizeof(Block)); current = current->next; } current->next = NULL; // Last block points to NULL }
この関数内:
メモリを割り当てるには、空きリストから最初に使用可能なブロックを取得する必要があります。ブロックを割り当てたら、そのブロックを空きリストから削除します。
#include <stdio.h> #include <stdlib.h> #include <stddef.h> #define POOL_SIZE 1024 // Total memory pool size // Define a block structure with a pointer to the next free block typedef struct Block { struct Block *next; } Block; // Define the MemoryPool structure typedef struct { Block *freeList; unsigned char pool[POOL_SIZE]; // Pre-allocated pool } MemoryPool;
この関数は、空きリストが空かどうかを確認します。そうでない場合は、最初の空きブロックを取得し、空きリストから削除して、呼び出し元に返します。
メモリが解放されると、ブロックを空きリストに戻します。これにより、将来の割り当てに再利用できるようになります。
void initMemoryPool(MemoryPool *pool) { pool->freeList = (Block *)pool->pool; Block *current = pool->freeList; // Create a free list of blocks for (int i = 0; i < (POOL_SIZE / sizeof(Block)) - 1; i++) { current->next = (Block *)((unsigned char *)current + sizeof(Block)); current = current->next; } current->next = NULL; // Last block points to NULL }
ここでは、フリー リストの現在の最初のブロックに次のポインターを設定することにより、フリー リストの先頭に解放されたブロックを追加します。これにより、将来ブロックを再利用できるようになります。
必要な関数がすべて揃ったので、すべてをまとめてメモリ プール アロケータをテストしましょう。
void *allocateMemory(MemoryPool *pool) { if (pool->freeList == NULL) { printf("Memory pool exhausted!\n"); return NULL; } // Get the first free block Block *block = pool->freeList; pool->freeList = block->next; // Move the free list pointer return (void *)block; }
この例では:
このプログラムを実行すると、次のような出力が表示されるはずです。
void freeMemory(MemoryPool *pool, void *ptr) { Block *block = (Block *)ptr; block->next = pool->freeList; // Add the block to the free list pool->freeList = block; }
メモリ プールは、低遅延とメモリ効率が重要である リアルタイム システム、組み込みシステム、および ゲームで特に役立ちます。
独自のメモリ プール アロケータを作成すると、パフォーマンスが重要なアプリケーションのメモリ管理を大幅に最適化できます。メモリを直接管理することで、割り当て速度を向上させ、断片化を軽減し、プログラム内でのメモリの使用方法をより詳細に制御できるようになります。この例は基本的なものですが、さまざまなブロック サイズやスレッドセーフなメモリ割り当てなどの追加機能を使用して拡張できます。
効率的なメモリ管理が必要なプロジェクトに取り組んでいる場合は、独自のメモリ プールの実装を検討してください。これは、メモリ管理をさらに深く掘り下げ、アプリケーションのパフォーマンスを向上させる優れた方法です。
ご質問がある場合、またはさらに詳しい説明が必要な場合はお気軽にお問い合わせください。コーディングを楽しんでください! ?
以上がC で独自のメモリ プール アロケータを作成するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。