memory leak when deleting derived class with base-

2019-06-24 19:13发布

I have an issue with a memory leak. I have a base-class pointer. From it, I use new to allocate different derived classes. Then, when I try to delete those classes with the reference (not typecasted), I get a memory leak. I researched the problem and found that I should add a virtual destructor to the base-class, but I tried this and I still have a memory leak; that is, according to my task-manager, the memory usage continues to rise with each allocation and deletion of the derived class using the base-class pointer. I tried making it an abstract destructor and added destructors to the derived classes, but I got an undefined reference error. I also tried typecasting the pointer as a derived-class pointer for the delete, but apparently this crashes the program.

Does anyone have any idea what I should do?

Example code:

class A {
public:
  A();
  ~A() {};
  virtual ~A();      /*or*/
  virtual ~A()=0;    /*or*/
                     /*or nothing?*/
}

class B: private A {
public:
  B();
  ~B() {};           /*this?*/
                     /*or nothing?*/
}

4条回答
贪生不怕死
2楼-- · 2019-06-24 19:37

You can use:

virtual ~A(){}

or

virtual ~A()=0; 

// as long as there is also:
A::~A(){}  // inline in the header file or non-inline in the cpp file.

This means that:

A* base;
...
delete base;

will call all the destructors of the derived classes in the correct order.

Note that a pure virtual destructor: virtual ~A()=0; can be useful if you need to have an abstract base class when no other member functions are pure virtual.

查看更多
一夜七次
3楼-- · 2019-06-24 19:42

use virtual ~A();

I'd be surprised if virtual ~A()=0 is allowed.

With this code:

A* base = new B();
delete base;

the destructor for B then A will be called.

If you're really still leaking memory, then you have another leak elsewhere.

查看更多
家丑人穷心不美
4楼-- · 2019-06-24 19:43

If you have a virtual destructor, the destructor(s) of your subclass(es) will all be called. no need to do any esoteric magic with abstract deconstructors or anything.

I would assume the memory leak is somewhere inside your object. Maybe you're calling new() on something in B's (or A's?) constructor, but you don't delete it. Without seeing more code, all I can say is "your destructor setup is fine".

查看更多
可以哭但决不认输i
5楼-- · 2019-06-24 19:50

How sure are you that there really is a memory leak? Normally, the task manager won't be much help here, since it cannot tell how much of the memory belonging to your process is actually allocated. Even memory that is freed still belongs to your process, and may be used at later times by the memory management (normally malloc-like system library).

Use a tool such as mallocdebug, valgrind, purify etc. to find out if there's really a memory leak. These tools will replace the malloc implementation by a new one that keeps track of allocated memory and reports memory that is not freed upon process termination.

Note: On most systems, memory that is freed from a process is not returned to the system before the process exits. It is availabe for new allocations from within the same process, though.

查看更多
登录 后发表回答