2

I am hunting memory leaks in a program.

I narrowed it down to some destructors not being called. However, I can't figure out why:

class CMain : public CList {
public:
    CMain();
    virtual ~CMain();
    ...
}

class CList : public CProc {
public:
    CList();
    virtual ~CList();
    ...
}

/* some code and a main func here */
CMain *pMain = new CMain();
/* some more code here */
delete pMain;

CMain gets deallocated just fine, but ~CList() is never called. All parent classes of CList have virtual destructors, too.

Do you have any hints about why the destructor for CList is never called?

bastibe
  • 16,551
  • 28
  • 95
  • 126

5 Answers5

3

Can you set a breakpoint in ~CMain to see where it goes?

wqking
  • 228
  • 1
  • 5
  • Doh. I only ever went a few steps into ~CMain. But you are correct. It never reaches the end of ~CMain. – bastibe Dec 22 '10 at 10:57
  • 1
    Congrats. Then will some more debugging, you may eventually find why it's not called. PS: checking the disassembly code may help. – wqking Dec 22 '10 at 11:08
2

Maybe there is a slicing problem somewhere. Just guessing..

What is object slicing? no, this is not that case.

You shuld put a try catch block in ~CMain, hmmm one of its member throw an exception in a destructor?

Community
  • 1
  • 1
  • What do you mean? What is a slicing problem? – bastibe Dec 22 '10 at 10:51
  • @BastiBechtold: See this: http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c – Naveen Dec 22 '10 at 10:54
  • If it was a slicing problem then derived class destructors will not be called, isn't it? but here it seems base class destructors are not getting called. – Naveen Dec 22 '10 at 10:56
1

Because you don't delete your object allocated with new.

;-)

More seriously, do you have gone into debugging the theoritical end of scope of one of your CList, and step into its destruction process, what happens?

Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
0

CMain gets deallocated just fine, but ~CList() is never called.

That sounds like a wrong statement. If ~CMain is called, then ~CList is eventually called too, because it's a base class. Check how you detect whether or not a destructor is called.

When you say "CMain gets deallocated", do you mean to say you issue delete on it? Check that at the point you do delete pMain, the class definition of CMain is visible. In absence of its definition, the compiler is allowed to assume the class doesn't have a user defined or virtual destructor, and can omit calling it.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
0

Child, then parent. But in between them, the attributes of the child are destroyed. I would suggest seeing if ~CMain runs to the end - if it does, and ~CList is never entered, you have a problem with one of the attributes of CMain.

Just to demonstrate:

#include <iostream>
#include <stdlib.h>

struct Owned {
    ~Owned() {
        std::cerr << "~Owned" << std::endl;
        exit(1);
    }
};

struct Parent {
    virtual ~Parent() {
        std::cerr << "~Parent" << std::endl;
    }
};

struct Owner : public Parent {
    ~Owner() {
        std::cerr << "~Owner" << std::endl;
    }

    Owned owned;
};

int main()
{
    Owner owner;
    return 0;
}

Outputs:

~Owner
~Owned

And exits with return code 1.

axw
  • 6,908
  • 1
  • 24
  • 14