5
BaseClass * p = new DerivedClass();
delete p;

I know the 2nd line will call the destructor of the base class if it doesn't have a virtual destructor and that of the derived class if it does but will delete properly free the memory (let's say BaseClass's object takes up 8 bytes of space and DerivedClass's one 12 - will it free 8 or 12 bytes) and get rid of the object in either case?

j0k
  • 22,600
  • 28
  • 79
  • 90
NPS
  • 6,003
  • 11
  • 53
  • 90
  • Are you familiar with `malloc`/`free` semantics? – Carl Norum May 11 '13 at 14:50
  • 1
    Re: " call the destructor of the base class" - maybe. If you delete an object of a derived type through a pointer to a base type and the base type does not have a virtual destructor the behavior is undefined. It might call the destructor for the base class, but it is not required to do that. – Pete Becker May 11 '13 at 15:39
  • 1
    @NPS Note that it is worth to mention that in case you created the DerivedClass object on the stack (i.e. - DerivedClass d;) than it does not matter at all if the BaseClass Dtor is virtual or not - the two of them (both of the Dtor's) will be invoked in a reverse order with respect to the construction of them (i.e. - DerivedClass and than BaseClass ). – Guy Avraham Jan 23 '17 at 06:47

2 Answers2

7

Well in the case that it has a virtual destructor, of course the object will be destroyed and the memory deallocated as expected. If it doesn't have a virtual destructor, the behaviour is undefined.

if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.

So it doesn't really make any sense to attempt to reason about whether the memory will be fully deallocated or not. The program can do whatever it likes with the memory.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
3

If the destructor isn't virtual, delete won't delete the derived class.

I tried this:

#include<iostream>

using namespace std;

class Base {
public:
    Base() {
        cout<<"Creating base."<<endl;
    }

    ~Base() {
        cout<<"Killing base."<<endl;
    }
};

class Derived: public Base {
public:
    Derived() {
        cout<<"Creating derived."<<endl;
    }

    ~Derived() {
        cout<<"Killing derived."<<endl;
    }
};

int main() {
    Base *p = new Derived();
    delete p;
    return 0;
}

Compiling on G++ 4.7.3 (default optimization), I get

Creating base.
Creating derived.
Killing base.

Note the absence of Killing derived.

Anubhav C
  • 2,631
  • 2
  • 18
  • 23
  • As I understand it, the destructor is only a means of doing manual cleanup before the object **is actually destroyed by the program**. So, correct me if I'm wrong, but I think this code proves nothing. – NPS May 11 '13 at 15:04
  • [`delete` both runs the destructor and frees the memory](http://stackoverflow.com/a/677661/1321855) if the memory is allocated on the heap (as it is when you allocate memory using `new`). If the destructor isn't being called, I think it's safe to say that the memory isn't being freed either. – Anubhav C May 11 '13 at 15:09
  • @AnubhavC I took your answer further down the line , and added some more points one should consider. In case you are intersted:http://stackoverflow.com/a/41801254/1971003 – Guy Avraham Jan 23 '17 at 08:31