Ist shared_ptr<int> foo(new int(0)) exceptionsicher?
-
Hallo zusammen,
ich hab mal eine kurze Nachfrage.
Istshared_ptr<int> foo(new int(0));exceptionsicher?
Also nach meiner Interpretation wird für den int Speicher alloziiert und dann für den Reference Counter im shared_pointer. Wenn die zweite Allocation fehlschlägt, hat man ein Memory leak...make_shared macht laut msdn nur eine Speicher-Allokation:
http://msdn.microsoft.com/en-us/library/ee410595.aspxAber im Bereich Why use this make_shared instead of operator new? steht nichts von zusätzlicher Exceptionsicherheit...
Ist der Code von oben exceptionsicher?
Gruß,
XSpille
-
Wenn der ctor eine Exception wirft, ruft er vorher delete auf den übergebenen Zeiger auf. Ich hab jetzt kein Chapter&Verse, es erscheint mir nur logisch und kurzes Googeln durch die boost-Doku zeigt mir, dass ich vermutlich recht habe.
-
XSpille schrieb:
ich hab mal eine kurze Nachfrage. Ist
shared_ptr<int> foo(new int(0));exceptionsicher?
Ja. Wenn da irgend eine Ausnahme bei fliegt (im Konstruktor von shared_ptr), dann wird der Heap-allozierte int hier garantiert gelöscht. Habe ich eben gerade nachgeguckt (§20.7.2.2.1 [util.smartptr.shared.const])
Außer der Performanz (nur eine Allozierung statt zwei) bietet make_shared aber trotzdem eine höhere Ausnahmesicherheit.
void func(shared_ptr<foo>, shared_ptr<bar>); int main() { // schlecht, nicht Ausnahme-sicher func(shared_ptr<foo>(new foo),shared_ptr<bar>(new bar)); // Warum? Weil die einzelnen Zeiger nicht sofort den // shared_ptrs übergeben werden müssen. Die Reihenfolge // bei dem, was hier passiert, ist unspezifiziert. Bevor // der erste Zeiger dem ersten shared_ptr übergeben wird // könnte schon der zweite new-Ausdruck ausgeführt werden, // welcher mit einer Ausnahme abbrechen könnte ==> // Speicherleck // Die Lösung: func(make_shared<foo>(), make_shared<bar>()); // Alternativ: shared_ptr<foo> pf (new foo); shared_ptr<bar> pb (new bar); func(pf,pb); }
-
krümelkacker schrieb:
Außer der Performanz (nur eine Allozierung statt zwei) bietet make_shared aber trotzdem eine höhere Ausnahmesicherheit.
void func(shared_ptr<foo>, shared_ptr<bar>); int main() { // schlecht, nicht Ausnahme-sicher func(shared_ptr<foo>(new foo),shared_ptr<bar>(new bar)); // Warum? Weil die einzelnen Zeiger nicht sofort den // shared_ptrs übergeben werden müssen. Die Reihenfolge // bei dem, was hier passiert, ist unspezifiziert. Bevor // der erste Zeiger dem ersten shared_ptr übergeben wird // könnte schon der zweite new-Ausdruck ausgeführt werden, // welcher mit einer Ausnahme abbrechen könnte ==> // Speicherleck // Die Lösung: func(make_shared<foo>(), make_shared<bar>()); // Alternativ: shared_ptr<foo> pf (new foo); shared_ptr<bar> pb (new bar); func(pf,pb); }Danke krümelkacker! Wie im anderen Thread schon erwähnt, man ist sich dessen manchmal nicht bewußt, obwohl man es eigentlich weiß
