Se elimino un oggetto che provoca il richiamo del suo distruttore, la memoria viene liberata prima o dopo che il distruttore ha terminato di eseguire qualsiasi cosa ci sia nella funzione?Distruttore C++: quando la memoria viene liberata?
risposta
La memoria viene liberata solo dopo che il sottoprogetto di classe meno derivato è stato distrutto. Quindi, se avete:
class Base {
};
class Derived : public Base {
public:
~Derived();
};
poi la prima Derived
è distrutto, poi Base
è distrutta e solo allora la memoria si rilascia.
La memoria viene liberata una volta terminato il distruttore. Altrimenti, l'accesso alle variabili membro all'interno del distruttore causerebbe segfault.
operatore delete viene chiamato dopo destructor, ma quando la memoria viene liberata è fino a allocatore usate
penserei che la memoria viene liberata dopo la funzione distruttore stessa ha terminato l'esecuzione. So che quando viene rilevata un'eccezione, il distruttore dell'oggetto non viene chiamato fino a quando l'oggetto stesso non rientra nello scope.
Decompone delete
in quello che effettivamente sta facendo ed è relativamente chiaro vedere quando la memoria viene cancellata. Quindi una dichiarazione come questa:
delete some_ptr;
è più o meno equivalente a questa pseudo-codice:
some_ptr->~some_ptr();
free(some_ptr);
Così la memoria viene liberata dopo la chiamata al distruttore. Esattamente ciò che fa il distruttore non è determinato dall'operatore delete
, ma piuttosto dalla definizione della classe. Di solito esegue la pulizia locale e assicura che vengano chiamati anche i suoi distruttori di classe base.
È importante rendersi conto che liberare la memoria non è in realtà parte del distruttore. È l'operatore delete
che libera la memoria.
Nota che la funzione free
in pseudo-codice è in realtà una delle operator delete()
funzioni, sia per la classe eliminato o globale. Questo in realtà libera la memoria.
Questo non è 'free()', questo è 'operator delete()'. – sharptooth
@sharptooth, puoi chiarire? Ho detto che era "pseudo-codice". –
Anche se è pseudocodice, C++ usa 'operator delete()' - globale o specifico della classe - per deallocare la memoria con l'istruzione 'delete'. – sharptooth
In C++, la distruzione consiste nell'eseguire un codice utilizzando i dati disponibili nell'oggetto. Questo codice è arbitrario.
La memoria libera è una gestione di basso livello, nascosta dall'operatore delete
in generale, che non dovrebbe mai essere chiamata prima delle chiamate al distruttore.
Questo è meglio riassunte dall'interfaccia Allocator:
allocate
edeallocate
sono utilizzati per manipolare memoria nonconstruct
edestroy
sono utilizzati per chiamare i costruttori e distruttori degli oggetti
Si precisa che construct
, destroy
e deallocate
devono essere eseguiti solo o n memoria precedentemente allocata da tale allocatore. Precisa anche che destroy
non rilascia la memoria e che sia necessaria una chiamata successiva a deallocate
.
Si noti che questa è un'interfaccia di basso livello, che consente di distruggere un oggetto e riutilizzare lo spazio liberato per costruirne un altro sul posto.
- 1. La memoria perduta viene liberata quando si esce dal programma?
- 2. Quando verrà liberata memoria C della struttura
- 3. la memoria allocata da kmalloc() viene liberata automaticamente?
- 4. La memoria di un array (di caratteri) viene liberata andando fuori campo?
- 5. Dove viene allocata la memoria quando creo questo array? (C)
- 6. Quando viene rilasciata la memoria in relazione a variabili statiche?
- 7. Cosa succede alla memoria che non viene liberata dopo la fine del programma?
- 8. Distruzione di membri della classe quando distruttore non viene chiamato
- 9. Un distruttore viene chiamato quando un oggetto esce dall'oscilloscopio?
- 10. La memoria viene rilasciata quando lancio un'eccezione?
- 11. C++ distruttore di default
- 12. Come dovrebbe essere liberata la memoria dopo che un'eccezione è stata lanciata in C++?
- 13. Il C# ripulisce la memoria allocata C++?
- 14. Come viene mappata la memoria quando si utilizza la forcella?
- 15. Distruttore virtuale: è richiesto quando la memoria allocata non è dinamica?
- 16. riferimento e distruttore in C++
- 17. Codice distruttore C++
- 18. L'heap viene liberato quando il programma termina?
- 19. Se/Quando viene recuperata la memoria heap dealloca?
- 20. Ctypes Structures e POINTERS liberano automaticamente la memoria quando l'oggetto Python viene cancellato?
- 21. Objective-C - Test per l'istanza dell'oggetto deallocata/liberata
- 22. C++ utilizzando getline() stampe: puntatore viene liberata non è stata allocata in XCode
- 23. EventHandlers e C# Classi distruttore/Dispose
- 24. Objective-C distruttore con ARC
- 25. Quando dovrei creare un distruttore?
- 26. Quando esattamente si chiama il distruttore in C++
- 27. distruttore chiamato quando gli oggetti sono passati per valore
- 28. distruttore non chiamato quando ritorno un'istanza locale
- 29. Vernice lenta quando l'oggetto viene memorizzato nella cache (memoria)
- 30. Sapere dove viene allocata la memoria tramite FastMM
Esiste davvero una cosa del genere? Viene chiamato un determinato distruttore, che può essere virtuale se la classe lo dichiara come tale. Quel distruttore è responsabile della distruzione di tutti i sottooggetti, e quindi la memoria viene liberata. Tutti i sottooggetti senza classi base sono ugualmente di derivazione minima e nessuno ha una particolare responsabilità o significato. – Potatoswatter
@Potatoswatter: Nota Non ho specificato chi è esattamente responsabile della chiamata alla funzione di deallocation - esattamente perché farlo in tutti i dettagli richiederebbe una risposta di due pagine. – sharptooth
@Potatoswatter: non sono sicuro di seguirlo. Nessun distruttore è responsabile della distruzione di oggetti secondari. Il distruttore è responsabile della liberazione delle risorse contenute in quell'oggetto, ma non deve (né deve) chiamare il distruttore di altri oggetti: 'class test {string a; ~ test() {}}; 'Il distruttore' ~ test' è perfettamente definito in questo esempio, non esiste una risorsa gestita direttamente dalla classe e non fa nulla. Il sistema chiamerà '~ string' sul sottobase' a' dopo che '~ test' ha completato l'esecuzione, non' ~ test'. Lo stesso vale per l'ereditarietà, il distruttore della base verrà automaticamente chiamato. –