Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What an implementation should do in case of operator new and "nested" initialization

Tags:

c++

I know that an implementation should free any allocated memory if the constructor of an object throws an exception in situation like this:

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

but what about the following code?

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

What should implementation do in this case? Should it free any allocated memory then?

like image 234
FrozenHeart Avatar asked Sep 05 '16 12:09

FrozenHeart


1 Answers

In the current C++ standard (C++14, as well as in the previous versions C++11 and C++03), it is unspecified whether memory is allocated before or after f() is evaluated, but in any case memory will be freed if it has been allocated; [expr.new]:

20 - If any part of the object initialization described above79 terminates by throwing an exception, storage has been obtained for the object, and a suitable deallocation function can be found, the deallocation function is called to free the memory [...]

79) This may include evaluating a new-initializer and/or calling a constructor.

Here the new-initializer is f(), so if the evaluation of f() throws an exception, the deallocation function will be called (if found).

Since C++17, the allocation of memory is sequenced before the evaluation of f(), so the memory will always be deallocated:

21 - If any part of the object initialization described above79 terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called [...]

Note though that since memory allocation is elidable, the implementation is in practice free to omit the allocation if it can predict that an exception will be thrown.

like image 154
ecatmur Avatar answered Nov 07 '22 04:11

ecatmur