Memory leak when deleting a derived class with a base class pointer

I have a memory leak problem. I have a base class pointer. From it, I use new to distribute various derived classes. Then, when I try to delete those classes with a link (not typecasted), I get a memory leak. I investigated the problem and found that I had to 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, memory usage continues to grow with each allocation and deletion of a derived class using a base class pointer. I tried to make it an abstract destructor and added destructors to the derived classes, but I got an undefined error. I also tried the typecasting pointer as a pointer to a derived class for delete , but apparently this is a program crash.

Does anyone know what I should do?

Code example:

 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
source share
4 answers

use virtual ~A();

I would be surprised if virtual ~A()=0 allowed.

With this code:

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

the destructor for B will be called, then A.

If you really still lose memory, you have another leak elsewhere.

+3
source

How sure are you that a memory leak is actually happening? Normally, the task manager will not be very useful here, since it cannot determine how much memory belonging to your process is actually allocated. Even freed memory is still relevant to your process and can be used in subsequent periods by memory management (usually a library in the form of a malloc-like system).

Use a tool like mallocdebug, valgrind, purify, etc. to find out if a memory leak is really happening. These tools will replace the malloc implementation with a new one that tracks allocated memory and report memory that is not freed up after the process is complete.

Note. On most systems, memory freed from the process does not return to the system until the process exits. However, it is available for new distributions from the same process.

+5
source

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

I would suggest that a memory leak is somewhere inside your object. Perhaps you are calling new() something in the constructor of B (or A?), But you are not deleting it. Without seeing any more code, all I can say is "your destructor setup is fine."

+3
source

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. 

It means that:

 A* base; ... delete base; 

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

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

0
source

Source: https://habr.com/ru/post/1342192/


All Articles