skip to Main Content

I get segmentation fault exception on the next code:

class A {
public:
    A() {}
    virtual ~A(){}
    double m_d;
};
class B : public A {
public:
    B() {}
    virtual ~B(){}
    int x;
};
int main()
{
    A* ptr = new B[5];
    delete[] ptr;
    return 0;
}

If delete d’tors, no exception.
Expected to NOT receive an exception.

Compiler: g++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0

2

Answers


  1. Array delete doesn’t respect virtual destructors. Attempting to pass a base class pointer to it causes undefined behavior.

    [expr.delete]/2

    … In a single-object delete expression, the value of the operand of delete may be a null pointer value, a pointer value that resulted from a previous non-array new-expression, or a pointer to a base class subobject of an object created by such a new-expression. If not, the behavior is undefined. In an array delete expression, the value of the operand of delete may be a null pointer value or a pointer value that resulted from a previous array new-expression.
    If not, the behavior is undefined.

    Note the second list excluding "base class subobject…" part.

    [expr.delete]/3

    … In an array delete expression, if the dynamic type of the object to be deleted is not similar to its static type, the behavior is undefined.

    Where "static type" is the type as determined at compile-time, "dynamic type" is the type of the most-derived object determined at runtime, and "similar" more or less means "the same type", but allows some differences in constness and more.

    Login or Signup to reply.
  2. This is not allowed, as described here: Why is it undefined behavior to delete[] an array of derived objects via a base pointer?

    Excerpt: C++03 Standard under 5.3.5 [expr.delete] p3: In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined

    I also made, out of curiosity, logging version:

    #include <iostream> 
    
    class A {
    public:
        A() {}
        virtual ~A(){ std::cout << m_d << " ; ";}
        double m_d {0.5};
    };
    class B : public A {
    public:
        B() {}
        virtual ~B(){ std::cout << x << " : "; }
        int x {2};
    };
    int main()
    {
        A* ptr = new B[5];
        delete[] ptr;
        std::cout << "Hi, nothing crashed here!n";
        return 0;
    }
    

    https://godbolt.org/z/Y7xGdKd3f

    Clang: calls base class destructor using incorrect data

    2.07634e-317 ; 0.5 ; 9.88131e-324 ; 2.07634e-317 ; 0.5 ; Hi, nothing crashed here!

    Gnu: politely crashes

    Program returned: 139

    M$: works as expected 🙂

    2 : 0.5 ; 2 : 0.5 ; 2 : 0.5 ; 2 : 0.5 ; 2 : 0.5 ; Hi, nothing crashed here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search