Explicit Call to Destructor Is Not Destroying My Object Why

Automatic destruction of object even after calling destructor explicitly

You've introduced undefined behavior.

Per the standard:

§ 12.4 Destructors

(11) A destructor is invoked implicitly

(11.3) — for a constructed object with automatic storage duration (3.7.3) when the block in which an object is
created exits
(6.7),

and

15 Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the
destructor is invoked for an object whose lifetime has ended (3.8). [ Example: if the destructor for an
automatic object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily
invoke implicit destruction of the object, the behavior is undefined. —end example ]

You explicitly call the destructor or by calling t.~Test(), it is then implicitly invoked when the object leaves scope. This is undefined.

The standard provides this note as well:

14 [ Note: explicit calls of destructors are rarely needed. One use of such calls is for objects placed at specific
addresses using a placement new-expression. Such use of explicit placement and destruction of objects can
be necessary to cope with dedicated hardware resources and for writing memory management facilities.

Explicit call to the destructor

It calls the destructor, but it doesn't deallocate the memory. Memory will be deallocated at the end of the function.

BTW, if you don't understand what happens, you probably shouldn't do that: the destructor will be called a second time at the end of the scope, which may cause issues if it can't be called twice (which is often the case).

Does calling a destructor explicitly destroy an object completely?

The answer is... nearly always.

If your object has a non-virtual destructor, and is then sub-classed to add child elements that need freeing... then calling the destructor on the object base class will not free the child elements. This is why you should always declare destructors virtual.

We had an interesting case where two shared libraries referenced an object. We changed the definition to add child objects which needed freeing. We recompiled the first shared library which contained the object definition.

HOWEVER, the second shared library was not recompiled. This means that it did not know of the newly added virtual object definition. Delete's invoked from the second shared library simply called free, and did not invoke the virtual destructor chain. Result was a nasty memory leak.

Why not call Destructor in C++?

Why destructor not call implicit by the compiler upon exit program?

Because dynamically allocated objects are not destroyed automatically. That is how the language has been specified. Tracking the destruction of dynamic objects would require runtime / memory overhead.

Solution: Do not leak dynamically allocated objects.

At which point of destructor call the object ceases to exist?

At which point of destructor call the object ceases to exist?

The lifetime of the object is ended by the call to its destructor. Within the destructor body, the sub-objects are still alive and member functions may be called. After the destructor body, the sub objects are destroyed.

if it's legal to call an object's function inside its destructor or not

It is legal.

Note however that calling a virtual function works differently than one might expect.

Is calling destructor manually always a sign of bad design?

Calling the destructor manually is required if the object was constructed using an overloaded form of operator new(), except when using the "std::nothrow" overloads:

T* t0 = new(std::nothrow) T();
delete t0; // OK: std::nothrow overload

void* buffer = malloc(sizeof(T));
T* t1 = new(buffer) T();
t1->~T(); // required: delete t1 would be wrong
free(buffer);

Outside managing memory on a rather low level as above calling destructors explicitly, however, is a sign of bad design. Probably, it is actually not just bad design but outright wrong (yes, using an explicit destructor followed by a copy constructor call in the assignment operator is a bad design and likely to be wrong).

With C++ 2011 there is another reason to use explicit destructor calls: When using generalized unions, it is necessary to explicitly destroy the current object and create a new object using placement new when changing the type of the represented object. Also, when the union is destroyed, it is necessary to explicitly call the destructor of the current object if it requires destruction.



Related Topics



Leave a reply



Submit