2013-10-12 8 views
13

Ich erkannte, dass nach dem Aufrufen von vector.clear(), die freigegebene Zeiger halten, die Destruktoren des Objekts, die durch shared_ptr besitzen nicht freigegeben werden.Vektor von geteilten Zeigern, Speicherprobleme nach dem Löschen des Vektors

Codebeispiel kann unten gesehen werden. Auch der Aufruf von vector.clear(), destructor, der nach Shared Pointer aufgerufen wird, geht über den scope.My Frage muss ich alle Smart Pointer innerhalb des Vektors manuell löschen, indem Sie sie zurücksetzen? Gibt es einen einfacheren Weg, den Sie beraten können?

Output : 

constructor 
I am here 
destructor 

Code: 

#include <vector> 
#include <iostream> 
#include <memory> 

using namespace std; 

class A 
{ 
public: 
    A(){cout << "constructor" << endl;}; 
    ~A(){cout << "destructor" << endl;}; 
}; 

int main() 
{ 
    shared_ptr<A> sharedptr (new A); 
    std::vector<shared_ptr<A> > test; 
    test.push_back(sharedptr); 

    test.clear(); 
    cout << "I am here" << endl; 
} 

Antwort

23

Sie haben zwei Kopien von shared_ptr<A> in diesem Fall ist eine der sharedptr Variable und das andere als ein Element in dem Vektor.

diese stattdessen

tun
test.push_back(std::move(sharedptr)); 

Notiz jetzt das Original sharedptr hat es intern verschobene ist und nicht mehr verwendbar. Die andere Sache ist überhaupt nichts zu tun, dies ist eine vollkommen gültige Verwendung von shared_ptr und sharedptr wird sich selbst bereinigen, nachdem es den Rahmen verlässt.

+0

Ihre Antwort ist genau das, was ich gesucht habe. Danke vielmals. –

+0

Ich würde hinzufügen, dass ich in dem in der Frage gezeigten Fall eigentlich vorziehen würde, den Vektor im Vektor über 'emplace_back' zu konstruieren, um eine zugängliche benannte Variable (' sharedptr') zu vermeiden, deren Verwendung danach gefährlich wäre 'std :: move'. – us2012

4

Das Problem tritt auf, wenn die push_back eine Kopie der shared_ptr zum Vektor hinzufügt, die ursprüngliche dangling, bis main existiert. Wenn Sie shared_ptr nicht im Hauptbereich ausführen, tritt das Problem nicht auf. Vermeiden Sie es, shared_ptr im Hauptbereich zu erstellen. Machen Sie es als temporäres Recht im Pushback-Aufruf.

Output is now: 

constructor 
I am almost there 
destructor 
I am here 

New code: 

#include <vector> 
#include <iostream> 
#include <memory> 

using namespace std; 

class A 
{ 
public: 
    A(){cout << "constructor" << endl;}; 
    ~A(){cout << "destructor" << endl;}; 
}; 

int main() 
{ 
    vector<shared_ptr<A> > test; 
    test.push_back(shared_ptr<A>(new A)); 
    cout << "I am almost there" << endl; 
    test.clear(); 
    cout << "I am here" << endl; 
    return 0; 
} 
+0

Was ist mit maked_shared oder emplace_back? – GameDeveloper

2

Hier sharedptr und das Element in Vektor das gleiche Objekt, das nur einmal in dem Aufruf und Destruktor führt.