私はC言語で単純なメモリプールを構築しました。このプールにメモリブロックを実装する機能も実装しました。Cメモリプールのメモリブロックのデフラグ
メモリブロック自体は非常に単純で、フリーフラグとサイズプロパティを持つ二重リンクリストです。
私が今しようとしているのは、割り当てられた(フリー== 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関数の呼び出しは、ちょうどその指定されたサイズに真の自由財産とサイズプロパティを設定し、ブロック構造として扱い、メモリアドレスを取得します。
私はGCCコンパイラを-std = C99フラグとともに使用しています。
割り当てられたブロックの所有者は、移転後どのようなことになりますか? –
@WeatherVane現時点では、所有者が保持しているポインタがuniの代入のために保持されている必要はありません。割り当ての中間ディレクトリを持ち、ポインタを持続させると、より高いマークが得られますが、それは低いマークの要件ではありません。 –
defraggerは、ユーザーがメモリポインタをどこに配置したかを知らないため、更新できません。確かに、未使用領域のデフラグのみが可能です。ハードディスクを最適化するときと同じように、開いているファイルは移動できません。 –