Weeedooo
Weeedooo

Reputation: 457

C++ destroying base class causes debug assertion failed

I'm trying to learn a bit more about polymorphism and I tried to make it as simple as possible, so I got base class Figure and 2 derived classes Rectangle and Circle.

class Figure {
public:
    Figure() { cout << "Creating Figure\n"; }
    virtual ~Figure() { cout << "Destroying Figure\n"; }

    virtual double calculateField() {
            return 0;
    }
};

class Rectangle : public Figure
{
public:
    Rectangle(double m_a) : p_a(m_a) { cout << "Creating Rectangle\n"; }
    ~Rectangle() { cout << "Destroying Rectangle\n"; }

    virtual double calculateField() {
        return p_a*p_a;
    }

private:
    double p_a; 
};

class Circle : public Figure
{
public:
    Circle(double m_r) : p_r(m_r) { cout << "Creating Circle\n"; }
    ~Circle() { cout << "Destroying Circle\n"; }

    virtual double calculateField() {
        return p_r*3.14*3.14;
    }

private:
    double p_r; 
};

In main function I create pointer to Figure class and 2 objects - rectangle and circle. Then I set Figure pointer on 1 of them and call calculateField() on this pointer. It works. But at the end I try to call delete on this pointer and it crashes my program.

int main(){
    Figure *ptr = new Figure();
    Rectangle rec(5);
    Circle circ(5);

    cout << "Figure field: " << ptr->calculateField() << endl;

    ptr = &rec; 
    cout << "Rectangle field: " << ptr->calculateField() << endl;

    ptr = &circ;
    cout << "Circle field: " << ptr->calculateField() << endl;

    delete ptr;

    cin.get();
    return 0;
}

Result of this looks like this:

Creating Figure
Creating Figure
Creating Rectangle
Creating Figure
Creating Circle
Figure field: 0
Rectangle field: 25
Circle field: 49.298
Destroying Circle
Destroying Figure

But then I got Debug Assertion Failed

Expression: _BLOCK_TYPE_IS_VALID(pHead -> nBlockUse)

Upvotes: 0

Views: 83

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 149125

You actually create a simple Figure at Figure *ptr = new Figure();, but, you immediately leak it by re-using ptr in ptr = &rec;

And just before calling delete you once again re-used the pointer in ptr = &circ;, so in fact you are calling:

delete &circ;

which is obviously an error.

In fact, everything will be correct provided you never use ptr in new or delete but a different pointer:

Figure *ptr, *ptr2 = new Figure();
...
delete ptr2;

Upvotes: 3

Bathsheba
Bathsheba

Reputation: 234795

The program behaviour is undefined.

You can only call delete on the pointer you get back from new.

Currently you're trying to delete something that has automatic storage duration. That is never going to end well.

Upvotes: 7

Related Questions