2012-09-14 5 views
16

Sto lavorando con std::shared_ptr e durante lo sviluppo del mio software ho incontrato un paio di di casi che mi lasciano dubbi sulla gestione della memoria. Avevo una libreria di terze parti che mi dava sempre dei puntatori grezzi dalle funzioni e nel mio codice li stavo trasformando in std::shared_ptr (da std e non da boost. A proposito, qual è la differenza tra i due? ?). Quindi cerchiamo di dire che ho il seguente codice:C++ pointer raw e std :: shared_ptr

ClassA* raw = new ClassA; 
std::shared_ptr<ClassA> shared(raw); 

Cosa succede ora quando il puntatore condiviso va fuori del campo di applicazione (diciamo è stato dichiarato a livello locale in una funzione e ora sto uscendo la funzione). L'oggetto ClassA esiste ancora perché punta un puntatore raw ?

risposta

27

No non lo farà. Dando il puntatore a shared_ptr stai dando a shared_ptr la responsabilità di cancellarlo. Lo farà quando l'ultimo oggetto shared_ptr che si riferisce ad esso non esiste più. I puntatori grezzi non contano.

+1

Solo per dare una ragione per cui: shared_ptr non considera il puntatore raw perché non c'è modo che shared_ptr possa saperlo. Se pensate a come implementare una shared_ptr da soli, vedrete che non potete rilevare se ci sono dei puntatori grezzi ai dati. – Wutz

+1

+1. Inoltre, questo è il motivo per cui dovresti 'new' l'oggetto sulla stessa riga quando crei' shared_ptr'. Ancora meglio, usa ['make_shared'] (http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared) –

+0

Grazie, in effetti sono d'accordo che non c'è modo di scoprire se un puntatore raw è indicando l'oggetto. In questo caso è pericoloso per il puntatore raw perché punta a un oggetto distrutto perché il parametro shared_ptr lo distruggerà quando è fuori portata – ISTB

2

No, ClassA l'oggetto sarà distrutto. A meno che non abbiate copiato lo scope shared_ptr in modo che il suo contatore di riferimento sia> 1.

5

no. Il puntatore condiviso lo cancellerà.

Se si dispone di una libreria di terze parti che fornisce un puntatore, è necessario assicurarsi di eliminarlo nel modo corretto. Se la lib di terze parti l'ha allocato con 'malloc' per esempio, allora devi usare l'implementazione di 'free' che usa lib. Devi essere sicuro di come è stato assegnato.

La libreria offre un modo per distruggere gli oggetti che fornisce? In tal caso dovresti usare quella funzione per distruggerla.