C で単純なメモリ プールを作成し、このプールにメモリ ブロックを実装する機能も実装しました。
メモリ ブロック自体は非常に単純で、free フラグと size プロパティを持つ二重にリンクされたリストです。
私が今やろうとしているのは、メモリ プールへのポインタを取得し、内部のメモリ ブロックをデフラグする関数を作成して、割り当てられた (free == 0) ブロックがプールの先頭に向かい、割り当て解除されたブロックが最後に向かうようにすることです。プールの。
たとえば、最適化関数を呼び出す前にメモリ ブロックが次のように構成されていたとします。
Block Size: 25 (41 w/ header), Free: 1
Block Size: 100 (116 w/ header), Free: 0
Block Size: 25 (41 w/ header), Free: 1
Block Size: 100 (116 w/ header), Free: 0
Block Size: 100 (116 w/ header), Free: 0
Block Size: 54 (70 w/ header), Free: 1
次に、関数を呼び出した後、ブロックは次のように配置されます。
Block Size: 100 (116 w/ header), Free: 0
Block Size: 100 (116 w/ header), Free: 0
Block Size: 100 (116 w/ header), Free: 0
Block Size: 25 (41 w/ header), Free: 1
Block Size: 25 (41 w/ header), Free: 1
Block Size: 54 (70 w/ header), Free: 1
私はすでに関数を構築しようとしましたが、正しいブロックを移動する際に問題が発生しました。これは、関数が呼び出された後の私の出力であるようです:
Block Size: 100 (116 w/ header), Free: 0
Block Size: 25 (41 w/ header), Free: 1
Block Size: 100 (116 w/ header), Free: 0
Block Size: 1744830464 (1744830480 w/ header), Free: 21
関数が間違った操作を実行している場所がまったくわからないので、誰かが私のためにこれに光を当ててくれることを願っています.
私のデフラグ機能:
void defragment(Pool* pool)
{
if(pool && pool->root)
{
Block* current = pool->root;
while(current)
{
if(!current->free)
{
Block* current_prev = current->prev;
if(current_prev && current_prev->free)
{
Block* prev_prev = current_prev->prev;
int new_block_size = current_prev->size;
Block* moved_current = memmove(current_prev, current, sizeof(Block) + current->size);
if(!moved_current)
{
printf("couldn't move memory\n");
}
else
{
Block* new_block = initBlock((((char*)moved_current) + sizeof(Block) + moved_current->size), new_block_size);
new_block->prev = moved_current;
new_block->next = moved_current->next;
moved_current->prev = prev_prev;
moved_current->next = new_block;
if(prev_prev)
{
prev_prev->next = moved_current;
}
current = moved_current;
continue;
}
}
}
current = current->next;
}
//Join Contiguous Blocks
}
}
initBlock 関数の呼び出しは、メモリ アドレスを受け取り、それを Block 構造体として扱い、free プロパティを true に設定し、size プロパティを指定されたサイズに設定します。
-std=C99 フラグを指定して GCC コンパイラを使用しています。