Search code examples
c++inheritanceallocation

Improper usage of new with inheritance?


I am trying to figure out a crash, and have boiled it down the following sample:

class Base
{
public:
    virtual unsigned int    GetNum  () = 0;
};

class Derived : public Base
{
    int data;   // <--- commmenting this out removes the crash

public:
    Derived() {}
    virtual unsigned int    GetNum() { return 1; }
};

void func() {

    Base** ppBases;

    unsigned int xLen = 3;
    unsigned int yLen = 4;

    ppBases = new Base*[xLen];
    for(unsigned int x = 0; x < xLen; ++x) {
        ppBases[x] = new Derived[yLen];
        for(unsigned int y = 0; y < yLen; ++y) {
            Base* curBase = dynamic_cast<Base*>(&(ppBases[x][y]));
            Derived* curDerived = dynamic_cast<Derived*>(&(ppBases[x][y])); // <--- crashes with a null dereference
            unsigned int result = curBase->GetNum();
            result = result;
        }
    }
}

I guessed that Derived isn't actually being allocated with the proper size. Changing ppBases to be a tripple pointer (like so) makes everything work:

void func() {

    Base*** ppBases;

    unsigned int xLen = 3;
    unsigned int yLen = 4;

    ppBases = new Base**[xLen];
    for(unsigned int x = 0; x < xLen; ++x) {
        ppBases[x] = new Base*[yLen];
        for(unsigned int y = 0; y < yLen; ++y) {
            ppBases[x][y] = new Derived();
            Base* curBase = dynamic_cast<Base*>(ppBases[x][y]);
            Derived* curDerived = dynamic_cast<Derived*>(ppBases[x][y]);
            unsigned int result = curBase->GetNum();
            result = result;
        }
    }
}

I don't understand why though.

Thanks


Solution

  • The problem is with this line:

     ppBases[x] = new Derived[yLen];
    

    You're assigning an array of Derived objects to a Base * pointer. So when you write ppBases[x][y] the compiler works with the type of the pointer, which is Base *, and index appropriately. So ppBases[x][1] does not refer to the second Derived object in the allocated array.