Not a virtual destructor in the base class, but a virtual destructor in the derived class causes a segmentation error

Recently, during an interview, I was asked about the problem of memory leak in derived classes when the base class destructor is not declared virtual.

I wrote a small test to confirm my answer, but found something interesting. Obviously, if you create the Derived object via new , but save its pointer as Base* , the destructor of the derived object will not be called if the pointer is deleted (so much for my answer to the question).

I thought that the virtual or destructor of the derived class is relevant in this case, but on my system the following code shows differently:

 #include <iostream> #include <string> // just a helper class, printing its name out when it is destructed class PrintOnDestruct { public: PrintOnDestruct( const std::string& name ) : name_( name ) {} ~PrintOnDestruct() { std::cout << "Destructing: " << name_ << std::endl; } protected: std::string name_; }; // the Base class class Base { public: Base() { print_on_destruct_ = new PrintOnDestruct( "Base" ); } // the destructor is NOT virtual! ~Base() { delete print_on_destruct_; } protected: PrintOnDestruct* print_on_destruct_; }; // the NonVirtualDerived class, doesn't have a virtual destructor either class NonVirtualDerived : public Base { public: NonVirtualDerived() : Base() { print_on_destruct_child_ = new PrintOnDestruct( "NonVirtualDerived" ); } // the destructor is NOT virtual! ~NonVirtualDerived() { delete print_on_destruct_child_; } protected: PrintOnDestruct* print_on_destruct_child_; }; // the VirtualDerived class does have a virtual destructor class VirtualDerived : public Base { public: VirtualDerived() : Base() { print_on_destruct_child_ = new PrintOnDestruct( "VirtualDerived" ); } // the destructor is virtual! virtual ~VirtualDerived() { delete print_on_destruct_child_; } protected: PrintOnDestruct* print_on_destruct_child_; }; int main() { // create the two child classes Base* non_virtual_derived = new NonVirtualDerived; Base* virtual_derived = new VirtualDerived; // delete the two objects delete non_virtual_derived; // works as expected (only calls Base destructor, the memory of NonVirtualDerived will be leaked) delete virtual_derived; // segfault, after calling Base destructor return 0; } 

I expected the program to output the following two lines and close normally:

 Destructing: Base Destructing: Base 

I get this conclusion, but right after the second line the program terminates with a segmentation error. And the message:

 *** Error in `...': free(): invalid pointer: 0x00000000006020e8 *** 

I changed the order of the two calls to delete , but the program always made a call to delete virtual_derived; . Can someone tell me why this is?

+7
c ++ inheritance polymorphism destructor
source share
2 answers

The answer really is to state:

  Base* virtual_derived = new VirtualDerived; 

You are trying to "free" an address that was not returned by "malloc". To understand why, replace this line with

  VirtualDerived* x = new VirtualDerived; Base* virtual_derived = x; 

If you type these two addresses, you will notice that "x" and "virtual_derived" have different meanings. The address that "malloc" returned (via "new") is "x", and the address that was transmitted "free" (via "delete") is "virtual_derived".

+7
source share

You must declare the destructor in the base class as virtual , which you do not do in this example. Declaring it as virtual in a derived class is just not enough.

+2
source share

All Articles