Con blocchi di dimensioni fisse, quello che hai descritto è un elenco gratuito . Questa è una tecnica molto comune, con la seguente svolta: l'elenco dei blocchi liberi è memorizzato nei blocchi liberi stessi. Nel codice C, sarebbe simile al seguente:
static void *alloc_ptr = START_OF_BIG_SEGMENT;
static void *free_list_head = NULL;
static void *
allocate(void)
{
void *x;
if (free_list_head == NULL) {
x = alloc_ptr;
alloc_ptr = (char *)alloc_ptr + SIZE_OF_BLOCK;
} else {
x = free_list_head;
free_list_head = *(void **)free_list_head;
}
return x;
}
static void
release(void *x)
{
*(void **)x = free_list_head;
free_list_head = x;
}
Funziona bene fintanto che tutti i blocchi allocati hanno le stesse dimensioni e tale dimensione è un multiplo della dimensione di un puntatore, in modo da mantenere l'allineamento. Allocazione e deallocazione sono a tempo costante (ovvero, a tempo costante come gli accessi alla memoria e le aggiunte elementari) in un computer moderno, un accesso alla memoria può comportare errori di cache e persino memoria virtuale, quindi accessi al disco, quindi il "tempo costante" può essere abbastanza grande). Non c'è sovraccarico di memoria (nessun puntatore per blocco extra o cose del genere; i blocchi allocati sono contigui). Inoltre, il puntatore di allocazione raggiunge un dato punto solo se, contemporaneamente, dovevano essere allocati molti blocchi: poiché l'allocazione preferisce usare la lista libera, il puntatore di allocazione viene aumentato solo se lo spazio sotto il puntatore corrente è pieno. In tal senso, tecnica.
Decrescenteil puntatore di allocazione dopo un rilascio può essere più complesso, poiché i blocchi liberi possono essere identificati in modo affidabile solo seguendo l'elenco libero, che li attraversa in un ordine imprevedibile. Se per te è importante ridurre le dimensioni del segmento grande, se possibile, potresti voler usare una tecnica alternativa, con più overhead: tra due blocchi allocati, metti un "buco". I fori sono collegati tra loro con un elenco doppiamente collegato, in ordine di memoria. È necessario un formato dati per un foro in modo tale da poter individuare l'indirizzo iniziale del foro sapendo dove finisce e anche la dimensione del foro se si sa dove inizia il foro in memoria. Quindi, quando si rilascia un blocco, si crea un foro che si fonde con i fori successivi e precedenti, ricostruendo (ancora a tempo costante) l'elenco ordinato di tutti i fori. Il sovraccarico è quindi di circa due parole delle dimensioni di un puntatore per blocco assegnato; ma, a quel prezzo, è possibile rilevare in modo affidabile il verificarsi di un "foro finale", ovvero un'occasione per ridurre le dimensioni del segmento di grandi dimensioni.
Esistono molte varianti possibili. Un buon documento introduttivo è Dynamic Storage Allocation: A Survey and Critical Review di Wilson et al.