Search code examples
c++segmentation-faultnew-operatorderived-classdynamic-memory-allocation

Problem allocating derived class array with new


I have a simple program

$ cat a.cpp 
#include <iostream>
class MyClass {
    public:
        virtual void check() {
            std::cout << "Inside MyClass\n";
        }
};

class MyClass2: public MyClass {
    public:
        int* a;
        virtual void check() {
            std::cout << "Inside MyClass2\n";
        }
};

int main() {
    MyClass *w, *v;
    w = new MyClass2[2];
    v = new MyClass2;
    std::cout << "Calling w[0].check\n"; w[0].check();
    std::cout << "Calling v->check\n"; v->check();
    std::cout << "Calling w[1].check\n"; w[1].check();
}
$ g++ a.cpp
$ ./a.out 
Calling w[0].check
Inside MyClass2
Calling v->check
Inside MyClass2
Calling w[1].check
Segmentation fault

I thought it is possible to use new to allocate derived class objects. Also, v->check() seems to work fine.


Solution

  • w = new MyClass2[2]; 
    

    This creates an array of two MyClass2 objects. It is of type MyClass2[2]. The new expression returns a pointer to the initial element of this array and you assign that pointer to w.

    w[1].check();  
    

    This treats w as a pointer to an array of MyClass objects, not as an array of MyClass2 objects.

    You cannot treat an array of derived class objects as if it were an array of base class objects. If you want to be able to use the derived-class objects, you need an array of pointers:

    MyClass** w = new MyClass*[2];
    w[0] = new MyClass2;
    w[1] = new MyClass2;