2016-09-05 6 views
8

wiem, że realizacja powinna uwolnić każdą przydzieloną pamięć jeśli konstruktor obiektu zgłasza wyjątek w sytuacji tak:Co implementacja należy zrobić w przypadku operator new i „zagnieżdżonych” inicjalizacji

new T(); // Suppose that T() throws an exception 

ale co z następującym kodem?

new T(f()); // Suppose that T() does NOT throw any exception, but f() does 

Co należy zrobić w tym przypadku? Czy powinno to zwolnić przydzieloną pamięć?

+0

Implementacja powinna zwolnić pamięć, która została przydzielona dla obiektu 'T'. –

Odpowiedz

4

W bieżącym standardzie C++ (C++ 14, jak również w poprzednich wersjach C++ 11 i C++ 03) nie określono, czy pamięć jest alokowana przed czy po ocenienie f(), ale w dowolnym pamięć case zostanie zwolniona, jeśli została przydzielona; [expr.new]:

20 - Jeżeli część inicjalizacji przedmiotu opisanego powyżej kończy rzucając wyjątek składowanie uzyskano dla obiektu i odpowiedni może być funkcja dealokacji znalezione, funkcja dealokacji jest zwane zwolnienia pamięci [...]

79) może obejmować oceniania nową-inicjator i/lub wywołanie konstruktora.

Tutaj nowych inicjator jest f(), więc jeżeli ocena f() zgłasza wyjątek, funkcja dealokacji będzie nazywany (jeśli stwierdzono).

ponieważ C++ 17, przydział pamięci sekwencjonuje przed ocenę f() tak pamięci zawsze zwalniane:

21 - Jeżeli część inicjalizacji przedmiotu opisanego powyżej kończy rzucając wyjątek i odpowiedniej funkcji dealokacji można znaleźć, funkcja dealokacji nazywa [...]

proszę zauważyć, że ponieważ MEMOR y alokacja jest elidable, implementacja jest w praktyce swobodny, aby pominąć przydział, jeśli można przewidzieć, że wyjątek zostanie rzucony.

+0

Wielkie dzięki. A co z C++ 98/C++ 03 i C++ 11? – FrozenHeart

+1

@FrozenHeart C++ 11 i C++ 03 są takie same jak C++ 14. – ecatmur

+0

Ah, dzięki. "nie jest sprecyzowane, czy pamięć jest alokowana przed czy po f() jest oceniana" - myślę, że to samo dotyczy również konstruktora 'T'? – FrozenHeart

Powiązane problemy