2012-09-14 5 views
16

Ich arbeite mit std::shared_ptr und während meiner Softwareentwicklung traf ich ein paar von Fällen, die mich Zweifel über Speicherverwaltung lassen. Ich hatte eine Third-Party-Bibliothek, die mir immer rohe Zeiger von Funktionen gab und in meinem Code transformierte ich sie in std::shared_ptr (von Std. Und nicht von Boost. By the way was ist der Unterschied zwischen die beiden?). Also lassen Sie uns sagen, dass ich den folgenden Code haben:C++ roher Zeiger und std :: shared_ptr

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

Was jetzt geschieht, wenn der gemeinsame Zeiger den Gültigkeitsbereich verlässt (sagen wir, es wurde vor Ort in einer Funktion deklariert und jetzt habe ich die Funktion am Verlassen). Wird das ClassA Objekt noch existieren, weil ein roher Zeiger darauf zeigt?

Antwort

27

Nein, wird es nicht. Indem Sie den Zeiger auf shared_ptr angeben, geben Sie shared_ptr die Verantwortung für das Löschen. Dies geschieht, wenn das letzte shared_ptr-Objekt nicht mehr existiert. Rohe Zeiger zählen nicht.

+1

Nur um einen Grund zu geben warum: shared_ptr berücksichtigt den rohen Zeiger nicht, da es keine Möglichkeit gibt, dass shared_ptr darüber informiert werden könnte. Wenn Sie darüber nachdenken, wie Sie selbst ein shared_ptr implementieren würden, werden Sie feststellen, dass Sie nicht erkennen können, ob es rohe Zeiger auf die Daten gibt. – Wutz

+1

+1. Aus diesem Grund sollten Sie das Objekt in der gleichen Zeile "neu erstellen", wie Sie das 'shared_ptr' erstellen. Noch besser, benutze ['make_shared'] (http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared) –

+0

Danke, in der Tat stimme ich zu, dass es keine Möglichkeit gibt herauszufinden, ob ein roher Zeiger ist auf das Objekt zeigen. In diesem Fall ist es nur gefährlich für den rohen Zeiger, weil es auf ein zerstörtes Objekt zeigt, weil das shared_ptr es zerstört, wenn es außerhalb des Bereichs liegt. – ISTB

2

Nein, ClassA Objekt wird zerstört. Sofern Sie nicht shared_ptr irgendwo außerhalb des Geltungsbereichs kopiert haben, so ist sein Referenzzähler> 1.

5

nein. Der geteilte Zeiger löscht es.

Wenn Sie über eine Bibliothek eines Drittanbieters verfügen, die Ihnen einen Zeiger zur Verfügung stellt, müssen Sie sicherstellen, dass Sie ihn auf die richtige Weise löschen. Wenn die 3rd-Party-Bibliothek es zum Beispiel mit 'malloc' zuweist, dann müssen Sie die Implementierung von 'free' verwenden, die die lib verwendet. Sie müssen sicher sein, wie es zugewiesen wurde.

Bietet die Bibliothek eine Möglichkeit, Objekte zu zerstören, die sie Ihnen zur Verfügung stellt? In diesem Fall sollten Sie diese Funktion verwenden, um es zu zerstören.