7
votes

I have a class:

class A
{
public:
    A()
    {
        std::cout << "Constructor called" << std::endl;
    }

    ~A()
    {
        std::cout << "Destructor called" << std::endl;
    }

    A(const A& another)
    {
        std::cout << "Copy constructor called" << std::endl;
    }

    A& operator=(const A& another)
    {
        std::cout << "Assignment operator= called" << std::endl;
    }
};

In my very complicated project, I got the following output after I started my app:

Constructor called

but when I Ctrl+C to terminate my app:

Destructor called
Destructor called

And in the whole process, no copy constructor or assignment operator got called.

My class A has dynamic memory allocation, and I have to free it in the destructor, but the destructor is called twice somehow, which is very bad.

I don't know what could cause this problem.

I googled and searched a lot. A lot of questions about "destructor called twice" is because of the the implicit calling of the copy constructor (assignment operator).

Thanks.

Peter

4
Shouldn't the "assignement operator" be operator= or am I missing something ? - ereOn
Sorry, a typo. I corrected it. - Peter Lee
Since you obviously have access to source code, couldn't you simply put breakpoint in destructor and see what's going on? - gwiazdorrr
Can you post a minimum compilable example where this problem shows up? - Matteo Italia
Can you provide snippets showing how A is used in your code? - Gregg

4 Answers

4
votes

If you are somehow calling the destructor twice, maybe you have two objects that think they own it through a pointer.

If you really do have two objects that think they own this one, consider using a reference counted pointer such as Boost::shared_ptr or tr1::shared_ptr to contain it. That way you don't have to worry about who calls the destructor finally.

Aside from the debugger, you could try Valgrind (memcheck) to find where your program deletes an already freed object. It probably won't give more detail than the debugger in this case, but you ought to learn to use Valgrind (memcheck) sooner or later.

Another paranoid strategy is to make sure to set any internal pointers to NULL after you delete them.

2
votes

Most likely either your have another constructor you aren't showing, OR you're calling the destructor more than once, either explicitly or via delete.

A debugger or additional couts will be more helpful than we can be in this case.

1
votes

Stick a breakpoint in the destructor. Then whenever it's called, you can grab a stack trace and see where it's being called from.

EDIT:

You can expect copy ellision to wreak havoc with trivial debugging statements like these.

1
votes

In my case I was using no pointers but destructor still got called twice. What I did to solve the problem is to override copy assignment operator MyClass& operator=(const MyClass& other). Not quite sure why auto-generated operator causes problems but appearently it does.