fdgdfg
fdgdfg

Reputation: 33

Extremely weird error involving polymorphism?

I have a class, let's call it A. It has a virtual function called myFunc.

class A {
    public:
          virtual void myFunc(){}
}

I then have a derived class, call it B.

class B: public A {
   public:
          void myFunc() {//does stuff}
}

I then have a function in another class called C, that takes an array of A's. This array actually is not of type A, it actually consists of elements of either B or another class derived from A.

class C {
    private:
           void anotherFunc(A myArray[], int index) {
                myArray[index].myFunc();
           }
}

I essentially want myFunc to be called, except the version implemented by the derived class that myArray really is, not the version implemented by A.

This works fine if index is 0. But for some reason, if it's any index other than 0, it crashes with a segfault (EXC_BAD_ACCESS).

So I tried the following:

1) I used by debugger to set a breakpoint in anotherFunc. For some reason, myArray is only being seen as an array of size 1, the other elements don't show up for some reason.

2) But if I change the function being called on myArray from myFunc to some other function that isn't virtual, it works fine for all indices...

Any idea what's going on?

Edit: This is how anotherFunc is being called.

B myArray[7];
//Initialize elements
anotherFunc(myArray, 2);

Upvotes: 3

Views: 64

Answers (1)

M.M
M.M

Reputation: 141633

This array actually is not of type A, it actually consists of elements of either B or another class derived from A.

A myArray[] (which actually reads A *myArray, since it is a function parameter), points to an array of A objects exactly. Arrays are homogeneous, i.e. all elements must be of the same type.

Your function is expecting an array consisting of A objects. However your code supplies an array consisting of B objects. Things are going to turn to custard as soon as you access beyond the first element of the array, because A and B objects have different sizes. When the compiler works out the memory address to access for myArray[1] for example, it will end up with an address part-way through the first B object; not the address of the second B object.

To fix this you need to make the function accept B *, or use a different container.

Upvotes: 7

Related Questions