Hardik
Hardik

Reputation: 185

Segmentation fault occur

#include <iostream>
using namespace std;
struct A 
{
     virtual ~A() {  cout << 0 << endl;};
};
struct B : A 
{
    int abc;
    ~B(){ cout << 3;}
};

int main() 
{
    A* ptr2 = new B[2];
    delete [] ptr2;
}

The above programs generates a run time error known as a seg fault. If I remove the abc variable from struct B, everything works great. Can anyone explain this behavior?

Upvotes: -3

Views: 84

Answers (1)

Jerry Coffin
Jerry Coffin

Reputation: 490128

This is a fairly common problem (or at least once was).

A pointer or reference to base can refer to an object of derived.

But a pointer or reference to base cannot reliably refer to an array of derived. If sizeof(derived) == sizeof(base) it'll often at least appear to work, but it's still wrong. And when their sizes differ, the problems will usually be quite visible.

The official, by-the-standard answer is just "don't do that."

Unofficialy the problem is that delete [] ptr2; doesn't know the size of the objects in the array ptr2 is referring to. Since ptr2 is a pointer to base, it tries to traverse the array as if it were an array of base objects. But when sizeof(derived) != sizeof(base), that doesn't work--it creates an offset into the array were the second object of the base type object would be, but since the array actually contains derived objects, that's (probably) somewhere in the middle of the first object instead of the beginning of the second object. Attempting to destroy that gives undefined behavior.

If you really need to do something like this, you can create an array of pointers to base, and initialize each of those pointers to refer to a derived object.

A ** ptr2 = new A*[2];
A[0] = new B;
A[1] = new B;

// ...

delete A[0];
delete A[1];
delete [] A;

Boost ptr_vector can help deal with the mechanics of this, in case you care;

Upvotes: 2

Related Questions