Reputation: 14138
Suppose I have a class A and a class B which inherits from A. Then I do something like:
A* a = new B();
delete a;
Why a memory leak happens only when there is a dynamic memory allocation within B? How C++ knows to remove the "B part" when there is dynamic memory allocations within B but fails where it is?
[Update:]
How does the following code does not result in a memory leak: [I suspect it to be undefined behaviour, but I don't really understand anything :(]
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
virtual void f() {
cout << "1" << endl;
}
~A() {
cout<< "A A'tor" << endl;
}
};
class B : public A {
private:
public:
B(){}
~B(){
cout<< "B D'tor" << endl;
}
void f() {
cout << "2" << endl;
}
};
int main() {
A* a = new B();
//a->f();
delete a;
return 0;
}
Upvotes: 1
Views: 916
Reputation: 395
This is because the destructor isn't virtual. If there is ever a chance in your program to delete derived class objects via base class pointers, you should define a virtual destructor in the base class. This will allow B's destructor to get called first, allowing you to free any dynamic memory B may have allocated. A's destructor will get called after B's.
Another good rule of thumb is to train yourself to think about making your destructor virtual anytime you make a method virtual. Since the motivation to make a method virtual means you will be calling methods on base class pointers, it follows that you will likely be deleting objects through base class pointers.
Upvotes: 0
Reputation: 2993
While compiler sees statement "delete a;"
It knows only static type of "a" is pointer to A, if there is no virtual destructor in class A. As a result wrong destructor gets called leading to memory leak
If there is a virtual destructor in class A then compiler comes to know that Dynamic type of "a" is pointer to B and there will a vtable from where it will get B's destructor address at run time
Upvotes: 1