C'ye basit bir bellek havuzu oluşturdum ve ayrıca bu havuzda bellek bloklarını uygulama becerisini de uyguladım.C Bellek Havuzunda Bellek Bloklarını Birleştirin
Bellek bloklarının kendileri oldukça basittir, yalnızca ücretsiz bir bayrak ve boyut özelliği olan bağlantılı bir liste.
Şu an yapmaya çalıştığım şey, bellek havuzuma bir işaretçi alan ve içindeki bellek bloklarını birleştiren bir işlev oluşturmaktır, böylece ayrılmış (boşta == 0) bloklar havuzun başlangıcına ve ayrılan bloklara doğrudur. havuzun sonuna doğru. Örneğin
, benim Birleştirmek işlevi aramadan önce hafıza blokları bu gibi yapılandırılmış olsaydı:
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
Sonra işlevini çağırarak sonra bloklar şöyle düzenlenebilir olacaktır:
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
Fonksiyonu oluşturmayı denedim ancak fonksiyondan sonra çıkışım olduğu gibi, etraftaki doğru blokları hareket ettirmek gibi bir problemle karşılaştım:
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
Fonksiyonun yanlış işlemleri gerçekleştirdiği yerde hiç emin değilim, bu yüzden birilerinin benim için biraz ışık tutacağını umuyorum.
Benim Birleştirmek fonksiyonu:
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 işlevine çağrı sadece bir bellek adresi alır Blok yapısı gibi davranır, daha sonra doğru ve verilen boyuta boyut özelliğine serbest özelliğini ayarlar.
GCC derleyicisini -std = C99 bayrağı ile kullanıyorum.
Tahsis edilen blokların sahibi, taşındıktan sonra ne yapacak? –
@WeatherVane Şu anda, uni için bir görev için olduğu gibi sahibinin devam ettiğini gösteren işaretçilere sahip olmam şart değildir. Tahsislerin bir ara dizinine sahip olmak ve işaretçilerin devam etmesini sağlamak bana daha yüksek işaretler ekleyse de, alt işaretler için bir gereklilik değildir. –
Defragger, kullanıcının bellek işaretleyicilerini nereye yerleştirdiğini bilmez, dolayısıyla bunları güncelleştiremezsiniz. Şüphesiz, kullanılmayan alanları yalnızca birleştirebilirsiniz. Sabit diski birleştirdiğinizde olduğu gibi, açık olan dosyalar taşınamaz. –