Destructor Being Called Twice When Being Explicitly Invoked

Destructor being called twice when being explicitly invoked

It happens because you told it to happen. The destructor for an automatic variable is always called when the variable goes out of scope. You also called it. That's two calls total.

Calling an object's destructor does not signal to C++ not to call it again, since in normal execution there is no need to keep track.

The solution is to never manually call your destructor.

Why is the destructor of the class called twice?

To add the element a copy constructor is invoked on a temporary object. After the push_back() the temporary object is destroyed - that't the first destructor call. Then vector instance goes out of scope and destroys all the elements stored - that's the second destructor call.

Destructor called twice

The last object is deconstructed two times.

Once when you explicitly destruct it, and then once again when the function ends and all variables local to the function auto-destruct. This is undefined behavior.

You should almost never call a destructor yourself.

Why is the destructor called twice for the same object?

I minimalized the example to

#include <cassert>
class A1 {
public:
virtual ~A1() {
assert(false);
}
};

class A2 : public A1 {
};

int main() {
A1* a = new A2;
delete a;
return 0;
}

with the assert to trigger a core dump.

Compiling with g++ 4.7.2, we get the double destructor backtrace in gdb

#0  0x00007f16060e92c5 in raise () from /usr/lib/libc.so.6
#1 0x00007f16060ea748 in abort () from /usr/lib/libc.so.6
#2 0x00007f16060e2312 in __assert_fail_base () from /usr/lib/libc.so.6
#3 0x00007f16060e23c2 in __assert_fail () from /usr/lib/libc.so.6
#4 0x00000000004007c8 in A1::~A1 (this=0xf60010, __in_chrg=<optimized out>) at double.cpp:6
#5 0x000000000040084d in A2::~A2 (this=0xf60010, __in_chrg=<optimized out>) at double.cpp:10
#6 0x0000000000400880 in A2::~A2 (this=0xf60010, __in_chrg=<optimized out>) at double.cpp:10
#7 0x000000000040078c in main () at double.cpp:15

while the backtrace of the same code compiled with g++ 4.3.2 looks similar but with only one frame for A2::~A2.

Both backtraces extracted with the same version of gdb (7.5.1).

So it is an artifact of the code generated by g++ 4.7, nothing to worry about for the behaviour of the compiled binary. It is not a real double call to the destructor.

Class and member destructors called twice

Any object that was created in a limited scope would be destroyed when the scope is exited.
Meaning, that if you have created an object on the stack, it will be destroyed when the stack will fold back, along with any other variables declared in that scope.

The only exception to this is when you are using dynamic allocation of objects, using the keyword new, this creates the object on the heap, which doesn't clean itself on its own. But even then, calling delete will invoke the destructor on its own.

Having said that, in order to avoid using new and delete, and for better resource management, there are types (such as smart-pointers) that handle these on their own, in a technique called Resource Allocation Is Initialization (or RAII), which makes things much simpler (and you get to the first part, all is allocated on the stack, thus the destructors are being called automatically when it folds).

Why is the destructor called twice?

The question has been asked many times before, but since it is so generic it is difficult to find the older posts.

You are passing your objects around by value, meaning that the copies are created by copy constructor. Copy constructor is what created that "extra object" in your case. Meanwhile, you do not output anything from the copy constructor and therefore don't see the calls.

You have to add a debug output to your copy-constructor as well. That way you will see what is actually constructed and when.

Destructor called twice causes crash

Your copy constructor leaves data uninitialized:

DebugClass::DebugClass(DebugClass const& other) 
{
cout << "copy construction\n";
}

So any use of data from that point on will give undefined behaviour.

If you simply set data to nullptr there, then you should not get the double deletion. Though you probably really want to do some form of copying from other.

This line:

DebugClass obj = DebugClass("Folder");

results in the copy constructor being called as part of constructing obj.

If you instead did:

DebugClass obj("Folder");

then obj would be constructed with the normal constructor.

C++ Method chaining causes destructor to be called twice

Foo f = Foo().bar(); also calls the copy constructor of Foo, which is currently the one the compiler generates and so doesn't output anything to the console. That's why it looks like you're calling more destructors than constructors.

You could write const Foo& f = Foo().bar(); to obviate a copy. Using a const also extends the lifetime of the anonymous temporary, which is nice.

Reference Counter and destructor being called twice

This is expected behavior.

Your design unfortunately isn't safe. If you create a scoped variable, increment it, copy it to a varible outside the scope, then the scoped variable will be destroyed (call decrement) and then, when you finally destroy the other variable, it will decrement a second time, crashing the program. Something like this:

RawModel rawModel;
{
RawModel temp;
temp.increment() //calls increment methods.
rawModel = temp;
} // destructor called once to clean up temp;
// destroy rawModel. destructor called twice to clean up rawModel;

And this is exactly what happens, will instantiace RawModel and then passes it to vector, which copies your variable inside, now you have two instances to call the destructor and break your program.

Options:
1. (Recommended) Use shared_ptr.
2. Define copy constructor and operator =, copying the content from one RawModel to another AND incrementing the count.

Although the second options sounds easier if you have some free time, go with option 1, learn shared_ptr, it'll help you a lot in future programs.

1.
shared_ptr<RawModel> rawModel = make_shared(new RawModel);
rawModel->increment() //increment stuff
vector.push_back(rawModel);
//now it'll work.

2.
//additional RawModel methods:
RawModel(const RawModel& rawModel) {
// copies everything and if it is initialized increment
}

const RawModel& operator =(const RawModel& other) {
//same as copy constructur
}

Hope this helps.

Manual call of destructor

Why destructor is called twice.

The first call is from the line i.~Test();.

The second call is the automatic call to the destructor when the variable i gets out of scope (before returning from main).

In first call of destructor memeber value is changed from 6 to 7 , still in second call it comes as 6.

That's caused by undefined behavior. When an object's destructor gets called twice, you should expect undefined behavior. Don't try to make logical sense when a program enters undefined behavior territory.

Can we stop second call of destructor (I want to keep only manually call of destructor).

You can't disable the call to the destructor of an automatic variable when variable goes out of scope.

If you want to control when the destructor is called, create an object using dynamic memory (by calling new Test) and destroy the object by calling delete.

GB::Test* t = new GB::Test(); // Calls the constructor
t->i = 6;
delete t; // Calls the destructor

Even in this case, calling the destructor explicitly is almost always wrong.

t->~Test();  // Almost always wrong. Don't do it.

Please note that if you want to create objects using dynamic memory, it will be better to use smart pointers. E.g.

auto t = std::make_unique<GB::Test>();  // Calls the constructor
t->i = 6;
t.reset(); // Calls the destructor

If t.reset(); is left out, the dynamically allocated object's destructor will be called and the memory will be deallocated when t gets out of scope. t.reset(); allows you to control when the underlying object gets deleted.



Related Topics



Leave a reply



Submit