La gestione della memoria e' forse l'aspetto PIU' COMPLESSO nella realizzazione di un programma poiche' l'efficienza/inefficienza della sua gestione ha un impatto DIRETTO sulle performance dell'applicazione stessa.
Invece di andare a casaccio, ci sono almeno 2 fonti autorevoli a cui fare riferimento:
1) The Art of Computer Programming, Volume 1, Capitoro 2: Dinamyc Storage Allocation
2) Garbage Collection: Algorithms for Automatic Dynamic Memory Management
per non parlare del gestore della memoria a livello hardware, usato dal sistema operativo (memoria segmentata, virtuale, paginazione, ...)
e del gestore della memoria del sistema operativo che la deve distribuire tra i vari processi, perche' COMUNQUE la memoria fisica e' quella installata e basta.
Per il C/C++ esiste una buona implementazione di un garbage collector:
https://en.wikipedia.org/wiki/Boehm_garbage_collecto
https://www.hboehm.info/gc
La possibilita' di ""compattare"" la memoria richiede un'infrastruttura abbastanza complicata.
Il problema e' questo:
-- non c'e' modo di sapere dove sono i puntatori che puntato ad una certa area di memoria.
Quindi, se questa viene spostata, non c'e' modo di aggiornare tutti i puntatori.
Una soluzione e' questa:
1) esiste un ""INDICE"" di TUTTI i blocchi di memoria allocati
2) i puntatori NON PUNTATO DIRETTAMENTE al blocco di memoria, MA tengono traccia SOLO dello SLOT all'interno dell'indice che contiene il puntatore al bocco di memoria a cui si e' interessati
3) l'accesso ad un'area di memoria richiede DUE accessi: p:puntatore -> slots[p] -> area allocata
4) la memoria puo' essere compattata perche' TUTTI i blocchi di memoria sono registrarti nell'INDICE (e SOLO QUI) e questo e' l'UNICO ad essere aggiornato quando i blocchi vengono mossi da una locazione di memoria all'altra
5) quando un blocco si libera, e' sufficiente indicare nell'indice che il corrispondente slot e' libero, oltre al fatto che anche il blocco e' libero
6) quando si alloca un nuovo blocco di memoria, si puo' fare una ricerca del primo slot libero ed usarlo per registrare la posizione del blocco di memoria
7) l'indice contiene le informazioni sui blocchi allocati e liberi, e quindi e' l'operazione di compattazione risulta molto semplice.
Dopo un po', OVVIAMENTE, sara' l'indice diventare come un gruviera, MA
1) l'indice NON PUO' ESSERE compattato per lo stesso problema iniziale
2) l'indice e' una struttura dati di dimensioni limitate e quindi la quantita' di memoria persa e' accettabile
3) ci sono strategie inteligenti per mantenere traccia degli slot liberi
C'e' un'altro BANALE problema:tempi di esecuzione, che NON SONO certamente dell'ordine dei millisecondi.
Comunque, l'approccio e' praticamente lo stesso della deframmentazione del disco.
-------------------------
L'accesso alle strutture dati interne del gestore della memoria del C/C++ non sono pubblicamente accessibili.
Comunque esistono librerie di terze parti in sorgente e i sorgenti del runtime a cui puo fare riferimento.
https://en.wikipedia.org/wiki/Dmallo
https://dmalloc.com
https://en.wikipedia.org/wiki/C_dynamic_memory_allocation
-------------------------
Per quanto riguarda Windows & C++ ci sono DUE tipi di heap:
1) l'heap gestito dal sistema operativo, che puo' essere manipolat mediante le API di windows, ma che DEVE essere usato per allocare GRANDI blocchi di memoria (qualche megabyte, NON CERTAMENTE bytes)
2) l'heap gestito dal GESTORE DELLA MEMORIA del linguaggio di programmazione usato il quale ha il compito di fare l'allocazione fine, cioe' soddisfare la singola richiesta dell'applicazione.
Quando l'heap del gestore della memoria e' terminato, l'applicazione richiede un nuovo blocco al sistema (qualche centinaio di kilobyte/megabyte) operativo.