Is the allocated memory for the object automatically deleted if an exception is thrown in the constructor?

Suppose there is this code:

class CFoo { public: CFoo() { iBar = new CBar(); } private: CBar* iBar; }; .... CFoo* foo = new CFoo(); 

When this line is executed, the first memory will be allocated to store the CFoo object. But if the CBAR () line throws an exception (due to out of memory), does the system automatically free the memory previously allocated for the CFoo object? I suppose he should, but cannot find any specific link, saying so. If this is not the case, how can memory be freed by the encoder since it will not be assigned to foo?

+4
source share
4 answers

Yes, the memory allocated for the CFoo object will be freed in this case.

Because the exception due to distribution failure causes the CFoo constructor to fail, the new expression guarantees the free memory allocated for this CFoo .

This warranty is specified in 5.3.4 [expr.new] / 17 ISO / IEC 14882: 2003.

Please note that it is always advisable to assign a dynamic highlight result to a smart pointer to ensure proper cleaning. For example, if another code appeared in the CFoo constructor, and this caused an exception, then the CBar object that was already successfully assigned earlier in the constructor would be leaked.

+6
source

Yes, but think about what happens if there is more than one member pointer:

 class CFoo { public: CFoo() { iBar = new CBar(); iBaz = new CBaz(); // Throws an exception } private: CBar* iBar; CBaz* iBaz; }; .... CFoo* foo = new CFoo(); 

Now the CBar object will be leaked. Using smart pointers instead of your own pointers will take care of this.

In addition, it is recommended to use element initializers:

 class CFoo { public: CFoo() : iBar(new CBar()) { // Nothing here } private: CBar* iBar; }; .... CFoo* foo = new CFoo(); 
+3
source

Yes - memory is automatically freed. Consider the following simplified pseudo pseudo operator new:

 template<typename T> T* operator new() { void* ptr = nullptr; try { ptr = ::operator new(sizeof(T)); return new (ptr) T(); } catch(...) { ::operator delete(ptr); throw; } } 
+1
source

If you intend to rely on the operator supplied by the new compiler, then in the above case the destructor will not be called. The reason is that when a new CBar () throws an exception, the stack expansion immediately begins, and the CFoo object is not "completely" constructed. Since this is a semi-line object, the compiler does not call the destructor for CFoo.

Rule of thumb: the destructor is called only for fully constructed objects in C ++

0
source

Source: https://habr.com/ru/post/1335891/


All Articles