2015-12-02 18 views
10

Es scheint, dass eine weak_ptr irgendwie weiß nur, wenn die shared_ptr es Referenzen wurde zerstört wurde. Wie ist das? Wird eine konstante Verbindung aufrechterhalten oder etwas?Was passiert mit einem weak_ptr, wenn sein shared_ptr zerstört wird?

Nehmen Sie die following code for example:

weak_ptr<int> test() { 
    shared_ptr<int> foo{new int}; 

    return foo; 
} 

int main() { 
    auto foo = test(); 

    cout << foo.expired() << endl; 
} 

Ich würde eine segfault erwarten, wenn die weak_ptr<int> auf dem Stand der shared_ptr<int> zu überprüfen geht, aber es ist nicht ein. Die weak_ptr<int> identifiziert den Speicher korrekt als freigegeben. Woher weiß es das?

+0

‚std :: weak_ptr‘ enthält einen Verweis auf einen gemeinsam genutzten Referenz zählen auf die gleiche Weise 'std :: shared_ptr' tut. Der einzige Unterschied ist, dass 'std :: weak_ptr' diese Anzahl nicht erhöht/verringert. –

+3

* Ich hätte einen segfault erwartet ... * Warum? das ist speziell der Punkt von weak_ptr – UmNyobe

+0

@UmNyobe Guter Punkt! Ich habe versucht zu kommunizieren, dass ich nicht verstanden habe, wie es funktioniert hat. –

Antwort

12

A std::shared_ptr erstellt wird unter Verwendung von zwei Stücken von Speichern:

  • ein Ressourcenblock: Dies hält den Zeiger auf die tatsächlichen zugrunde liegenden Daten, z.B. 'int *'

  • Ein Steuerblock: Enthält Informationen zu einem shared_ptr, z. B. Referenzzählungen.

(Manchmal sind diese in einem einzigen Teil des Speichers für die Effizienz zugeordnet sind, siehe std::make_shared)

Der Steuerblockauch speichert für weak_ptr Zählungen verweisen. Es wird nicht freigegeben, bis der letzte weak_ptr den Gültigkeitsbereich verlässt (der Zählerstand des schwachen Verweiszeigers fällt auf Null).

So ein weak_ptr wird wissen, dass es abgelaufen ist, weil es den Zugang zu diesem Steuerblock hat, und es kann überprüfen, um zu sehen, was der Referenzzähler für ein shared_ptr

ist
+0

Ich habe hier ein Missverständnis. Sie sagen also, dass der ** Kontrollblock ** tatsächlich 2 Zählungen speichert? Die Anzahl der 'weak_ptr's und die Anzahl der 'shared_ptr's? Und es wird nicht zerstört, bis BEIDE 0 sind? –

+2

@ JonathanMee: Das ist richtig. – AndyG

+2

@ JonathanMee: Ja, konzeptionell ist das was passiert. Übrigens können Sie Ihre Standardbibliothek Header-Dateien öffnen und sich die Implementierung selbst anschauen! –