2013-01-03 9 views
5

Per il piacere di questa domanda visualizzerò la memoria come una semplice matrice di byte e parlerò della memoria heap perché è possibile allocarla dinamicamente.Cosa succede esattamente quando si cancella my_object; viene eseguito? Tutta l'altra memoria è spostata a sinistra di sizeof (MyClass)?

Diciamo che sto creando un'istanza di alcune classi e creando un oggetto sull'heap in cui è già stata allocata memoria. Quindi, dopo aver creato l'oggetto, alloco ancora un po 'di memoria (magari istanziando un'altra classe). Ciò implica l'utilizzo delle parole chiave new e delete, ovviamente.

La memoria appare come segue:

... byte byte my_object ... my_object byte byte ...

Che cosa succede esattamente quando viene eseguito delete my_object;? Tutta l'altra memoria è spostata a sinistra di sizeof(MyClass)? Se è così, da chi? Il sistema operativo? Quindi cosa succede quando non ci sono sistemi operativi per fornire memoria virtuale?

+0

Grazie per la modifica Robert, ora è più chiaro. – corazza

risposta

6

No, niente viene spostato. Invece, la memoria diventa fragmented, il che significa che ora hai un buco inutilizzato nel mezzo della memoria utilizzata. Un'allocazione successiva potrebbe essere in grado di riutilizzare parte o tutta quella memoria (a condizione che il numero richiesto di byte sia abbastanza piccolo da adattarsi alla buca).

Alcuni linguaggi/ambienti supportano la compattazione dei garbage collector. Tali collezionisti sono autorizzati a muovere gli oggetti intorno e possono quindi eliminare i buchi se lo desiderano. Tali approcci sono complicati da implementare in quanto il raccoglitore deve conoscere la posizione di ogni singolo puntatore all'interno del programma. I collezionisti di questo tipo sono quindi più adatti per i linguaggi di livello superiore.

2

Se la memoria è stata spostata, sarebbe un OS IMO piuttosto male. In genere, il sistema operativo viene informato che tale memoria è disponibile per il riutilizzo. Non è nemmeno richiesto di essere cancellato (e il più delle volte non lo è). Quando non è possibile allocare più memoria, in genere si ottiene un'eccezione (se si utilizza new) o un puntatore NULL indietro (se si utilizza malloc).

Se la frammentazione è un problema (a volte è), dovrete scrivere il proprio pool di memoria è possibile utilizzare (esistenti) pool di memoria in grado di far fronte a questo, ma anche così, la maggior parte della responsabilità ancora cade sul programmatore.

1

In un'implementazione tipica (senza un garbage collector in movimento, ad esempio) non verrà spostato nulla.

Bames53 dice che Herb Sutter dice che lo standard dice che il movimento automatico degli oggetti assegnati è illegale. Grazie a Bames53.

+0

I garbage collector di compattazione (o comunque in movimento) non sono consentiti in C++. – bames53

+0

Cosa ti dà questa idea? – Zuu

+0

La specifica C++ richiede che i valori del puntatore siano stabili. Ad esempio, se un trucco viene utilizzato per nascondere un puntatore in modo che un garbage collector non possa interferire con esso, quando viene recuperato il valore del puntatore originale, deve comunque puntare all'oggetto originale. http://herbsutter.com/2011/10/25/garbage-collection-synopsis-and-c/ – bames53

2

La memoria non è spostata a sinistra. Immagina cosa succederebbe se lo fosse. Tutti quei puntatori "a destra" diventerebbero non validi.

+0

Il punto sui puntatori (NPI) è ottimo, +1. – corazza

Problemi correlati