0

Whilst studying inheritance in C++, I have learned that a base class intended for polymorphic behavior should implement it's destructor as virtual

I thought I understood how to apply this well, but I have encountered a small problem which I do not understand.

Given the following code:

#include <iostream>

struct Base
{
    Base() { std::cout << "Base ctor called\n"; };
    virtual ~Base() { std::cout << "Base dtor called\n"; };
};

struct Derived : Base
{
    Derived() : Base() { std::cout << "Derived ctor called\n"; }
    ~Derived() { std::cout << "Derived dtor called\n"; };
};

int main()
{
    Derived d;
    Base *p_base = &d;

    delete p_base; //Problem here?

    return 0;
}

Output is as expected:

Base ctor called
Derived ctor called
Derived dtor called
Base dtor called

However, a _CrtisValidHeapPointer(block) assertion error occurs.

Everything works fine if p_base points directly to a new Derived object i.e. Base *p_base = new Derived();

What is different here?

Kind regards

not an alien
  • 651
  • 4
  • 13
  • 3
    `delete`ing automatically allocated memory invokes undefined behaviour. One `delete` for every `new`, no more; no less. – George Aug 15 '18 at 22:28
  • All news should match up with deletes. You cannot have one without the other. – Christopher Pisz Aug 15 '18 at 22:28
  • 2
    Closely related/duplicate [Is it possible to delete a non-new object?](https://stackoverflow.com/questions/4355468/is-it-possible-to-delete-a-non-new-object). TL;DR: you can delete a pointer to an Automatic allocation, but the program will not survive the experience unscathed. – user4581301 Aug 15 '18 at 22:38
  • You can only `delete` objects that were created with `new`. – user253751 Aug 15 '18 at 22:52

1 Answers1

2

The problem is that your locally constructed object d will be deleted automatically at the end of its scope, in your case when return 0 is called. But at that time, you already deleted p_base which points to the same object. Hence the object is deleted twice.

Your problem has nothing to do with inheritance. It should arise even with objects of the same class.

vdavid
  • 2,434
  • 1
  • 14
  • 15
  • Thanks. Am I correct in assuming `p_base` would also be deleted at the same time, so I need not worry about a dangling pointer? – not an alien Aug 15 '18 at 22:53
  • `p_base` will not be deleted and it should not be deleted. When the scope ends `p_base` no longer exists. This is different than freeing dynamic memory. – drescherjm Aug 15 '18 at 22:58
  • 1
    @Jake you may have your terminology mixed up. A dangling pointer is what happens when what's being pointed at vanishes out from underneath a pointer, leaving the pointer pointing at invalid memory. Sometimes because this is because a pointer was assigned an Automatic variable that subsequently went out of scope. You seem to be concerned with a memory leak. Automatic storage cannot be leaked. The compiler ensures that. – user4581301 Aug 15 '18 at 23:00