2016-04-15 4 views
7

Mi chiedevo quando dovrei allocare una classe nello stack in C++? Ho un forte background in Java e in Java tutte le classi sono allocate nello heap, usando la parola chiave new. In C++ posso scegliere tra l'allocazione dello stack e dell'heap ma ora che vengono introdotti i puntatori intelligenti, ha più senso allocare tutto ciò che non trasferisce la proprietà con std::unique_ptr.Stack C++ vs allocazione heap

Non riesco a pensare a nessun caso, dove sarebbe necessario o meglio utilizzare l'allocazione dello stack. Forse per qualche tipo di ottimizzazione nei sistemi embedded?

+2

Solo un FYI un 'std :: unique_ptr' è un oggetto basato su" stack ". BTW chiamiamo quindi oggetti automatici e dinamici come C++ non ha alcun concetto di stack o heap. IMHO vuoi usare gli oggetti automatici quando possibile, – NathanOliver

+9

Normalmente usi il principio opposto: se l'allocazione dinamica non è necessaria, non lo fai. L'allocazione dinamica di default è "premessa di pessimizzazione". – molbdnilo

risposta

14

Uso automatico (stack) allocazione quando la funzione portata - o la portata di un blocco di controllo quale un for, while, if ecc all'interno della funzione - è una buona partita per la durata delle esigenze oggetto. In questo modo, se l'oggetto possiede/controlla qualsiasi risorsa, ad esempio memoria allocata dinamicamente, handle di file, ecc., Verranno liberati durante la chiamata del distruttore man mano che l'ambito viene lasciato. (Non in un momento successivo imprevedibile quando si verifica un immondizia).

Utilizzare solo new se c'è una chiara necessità, come ad esempio:

  • bisogno l'oggetto di vivere più a lungo la portata funzione,

  • di cedere la proprietà a qualche altro codice

  • per disporre di un contenitore di puntatori alle classi di base che è possibile elaborare in modo polimorfico (ovvero utilizzando dispacciamento virtuale per implementazioni di funzioni di classe derivata) o

  • una specie di grandi dimensioni di allocazione che mangiare gran parte della pila (OS/processo avrà "negoziata" un limite, di solito nel range 1-8 + megabyte)

    • se questo è l'unico Per quale motivo stai usando l'allocazione dinamica e vuoi che la vita dell'oggetto legato a un ambito nella tua funzione, devi usare un locale std::unique_ptr<> per gestire la memoria dinamica e assicurarti che venga rilasciato indipendentemente da come lasci l'ambito: per return, throw, break ecc. (È inoltre possibile utilizzare un membro di dati std::unique_ptr<> in un class/struct per gestire qualsiasi memoria di proprietà dell'oggetto.)

Mathieu Van Nevel commenti qui sotto semantica su C++ 11 spostare - la rilevanza è che se si dispone di un piccolo oggetto gestione dello stack che controlla una grande quantità di allocata dinamicamente (heap) di memoria, spostare la semantica garantisce garanzie extra e un controllo preciso di quando l'oggetto di gestione consegna le sue risorse a un altro oggetto di gestione di proprietà di un altro codice (spesso il chiamante, ma potenzialmente qualche altro contenitore/registro di oggetti). Questo passaggio di consegne può evitare che i dati sul mucchio vengano copiati/duplicati anche momentaneamente. Inoltre, elision e ottimizzazione del valore di ritorno spesso consentono alle variabili nominalmente automatiche/stack-hosted di essere costruite direttamente in qualche memoria a cui vengono eventualmente assegnate/restituite, piuttosto che copiate in seguito.

+0

questo è un buon riassunto. Recentemente ho rielaborato del codice che stava mettendo una serie di oggetti molto grandi nello stack. Se non stai attento, puoi esaurire lo spazio di stack in un programma più grande o in uno con ricorsione profonda. –

+0

Alcuni dettagli su C++ 11 si muovono semantici, e la risposta sarà perfetta penso: upvote –

+0

Buon riassunto, se aggiungi quando dovrei usare std :: unique_ptr invece di allocazione stack ti darò il tick della risposta. – KillerZefi

1

Nella base di codice grande viene utilizzata l'allocazione dello stack per oggetti struct semplici mentre per le classi più complesse (che implicano il polimorfismo, la proprietà della memoria, ecc.) Viene sempre utilizzata l'allocazione dinamica.