2015-08-20 9 views
17

Ein Steuerblock eines shared_ptr wird am Leben gehalten, während es mindestens einen weak_ptr vorhanden ist. Wenn der gemeinsame Zeiger mit make_shared erstellt wurde, bedeutet das, dass der gesamte Speicher des Objekts reserviert bleibt. (Das Objekt selbst ist ordnungsgemäß zerstört, aber da der Steuerblock und der Speicher für das Objekt in einem Chunk zugewiesen wurden, wie make_shared, können sie nur gemeinsam freigegeben werden.)weak_ptr, make_shared und Speicherfreigabe

Ist mein Verständnis korrekt?

Es scheint, dass dieses Verhalten ein Problem darstellt, zum Beispiel in den berühmten "cache example". Der Speicher für die Objekte wird für immer reserviert bleiben.

Es es ein Problem in allen praktischen Situationen? Soll die shared_ptr mit einem Konstruktor in einer solchen Situation erstellt werden (großes Objekt und Absicht, weak_ptr s zu verwenden)?

+1

, aber nicht vergessen viele „große“ Objekte werden ihre eigenen Speicher dynamisch, beispiels ein Objekt zuweisen, bestehend aus einem 'std :: VECTOR', so dass dynamisch zugewiesenen Speicher freigegeben werden _will_, wenn das Objekt zerstört wird. Sie müssen sich nur sorgen, wenn die Größe des Objekts selbst groß ist, z. B. ein großes 'std :: array'. –

+1

Wenn Sie sich Sorgen um die Sicherheit Ausnahme sind, könnten Sie 'statt make_unique' verwenden und dann eine' shared_ptr' von Ihrem 'unique_ptr' konstruieren: z' std :: shared_ptr ptr = std :: make_unique (); ' –

Antwort

9

Ist mein Verständnis richtig?

Ja. Wenn Ihr weak_ptr s das (große) Objekt deutlich überlebt und der Speicher knapp ist, kann es vorteilhaft sein, make_shared zu vermeiden.

jedoch „groß“ werden hier durch sizeof und viele konzeptionell „große“ Objekte (zum Beispiel der meist Standard-Container, mit Ausnahme std::array) sind recht klein, von dieser Metrik gemessen, weil sie zusätzliche Speicher zuweisen ihre Inhalte zu speichern, welches befreit wird, sobald das Objekt zerstört wird.

1

Ich habe versucht, dies in VS2013 und du bist völlig richtig. Der Destruktor wird aufgerufen, wenn der letzte shared_ptr zerstört wird, also werden alle anderen Objekte oder Speicher, die dem Objekt zugeordnet sind, zerstört, aber wenn shared_ptr mit make_shared erstellt wird, wird der Speicher niemals zerstört, bis der letzte weak_ptr ist.

Ich denke, es ist immer gut, um aufzuräumen oder Ihre weak_ptrs zurückgesetzt, wenn lock() schlägt fehl, da auch make_shared ohne es noch einige Speicher. Ja

Verwandte Themen