Can you please elaborate why this code crashes at the places mentioned? I am a bit stumped on this. I guess that it has got something to do with sizeof(int)
but I am not so sure. Can anybody explain?
class Base
{
public:
virtual void SomeFunction()
{
printf("test base\n");
}
int m_j;
};
class Derived : public Base {
public:
void SomeFunction()
{
printf("test derive\n");
}
private:
int m_i;
};
void MyWonderfulCode(Base baseArray[])
{
baseArray[0].SomeFunction(); //Works fine
baseArray[1].SomeFunction(); //Crashes because of invalid vfptr
baseArray[2].SomeFunction(); //Crashes because of invalid vfptr
baseArray[3].SomeFunction(); //Works fine
baseArray[4].SomeFunction(); //Crashes because of invalid vfptr
baseArray[5].SomeFunction(); //Crashes because of invalid vfptr
baseArray[6].SomeFunction(); //Works fine
baseArray[7].SomeFunction(); //Crashes because of invalid vfptr
baseArray[8].SomeFunction(); //Crashes because of invalid vfptr
baseArray[9].SomeFunction(); //Works fine
}
int _tmain(int argc, TCHAR* argv[])
{
Derived derivedArray[10];
MyWonderfulCode(derivedArray);
return 0;
}
sizeof(Derived)
is greater than sizeof(Base)
. That's the reason.
Generally, indexing an array of Foo
objects at index i
works the following way:
element_address = array_base_address + i * sizeof(Foo)
You can see how this indexing breaks if the array elements are not of expected size. Why it works for some indices is because sometimes the calculated element address points to a valid object in memory (but it's not actually the i
th object).
Never treat arrays polymorphically. The C++ language does not support that. (See also this Related question.)
Quote from this FAQ: Is array of derived same as as array of base?
Derived is larger than Base, the pointer arithmetic done with 2nd object baseArray is incorrect: the compiler uses sizeof(Base) when computing the address for 2nd object, yet the array is an array of Derived, which means the address computed (and the subsequent invocation of member function f()) isn’t even at the beginning of any object! It’s smack in the middle of a Derived object.
Arrays can't be used for storing objects of different types or for treating objects polymorphically - store pointers instead.
Sizes of Base
and Derived
are different - the code seeing the Base[]
array has no means to detect that it's really a Derived[]
array and just indexes the array incorrectly producing all sorts of undefined behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With