corrupted virtual function table?

N

NewToCPP

Hi,

I see a problem with the virtual functions when I new an array of
elements of the derived class type and get them using the base class
type.

In the program given below

type = msg->getMsgFormatType();

will crash the second time it goes through the loop. First time it
works fine. Second time it has problem. when I debug the code I
observed the following

first time:
msg
__vfptr ===> DerivedMsg::'vftable'


second time:
msg
__vfptr ===> ERROR expression






Code:
=========

enum FormatType
{
common,
derived
};

class CommonMsg
{

public:
virtual FormatType getMsgFormatType();

};
FormatType CommonMsg::getMsgFormatType()
{
return common;
}

class DerivedMsg:public CommonMsg
{
public:
unsigned char msgBuffer[55];
FormatType getMsgFormatType();
};

FormatType DerivedMsg::getMsgFormatType()
{
return derived;
}

class CommonMsgQ
{
protected:
CommonMsg *msg;

public:
virtual CommonMsg* getElement(int);

};


CommonMsg* CommonMsgQ::getElement(int index)
{
if (index < 5)
return (CommonMsg*) (&msg[index]);
else
return (CommonMsg*)0;
}

class DerivedMsgQ : public CommonMsgQ
{
public:
DerivedMsgQ (int);
CommonMsg* getElement(int);
};



DerivedMsgQ::DerivedMsgQ(int size)
{

msg = (CommonMsg *) new DerivedMsg[5];

}



CommonMsg* DerivedMsgQ::getElement(int index)
{
if (index < 5)
return (CommonMsg*) (&msg[index]);
else
return (CommonMsg*)0;
}



int main()
{

DerivedMsgQ dMsg(3);
CommonMsg* msg = (CommonMsg*)0;

for (int i =0; i<3; ++i)
{
msg = (CommonMsg*) 0;
msg = dMsg.getElement(i);
if (msg != (CommonMsg*) 0)
type = msg->getMsgFormatType();

}
return 0;
}
 
N

NewToCPP

The following change fixed the problem. Why should I type cast msg to
DerivedMsg*, does it already know that it is of type DerivedMsg* not
CommonMsg*?

Why does it work for the first element not for the subsequent ones?

Change that worked:
-----------------------------
CommonMsg* DerivedMsgQ::getElement(int index)
{
if (index < 5)
return (CommonMsg*) (&((DerivedMsg*)msg)[index]);
else
return (CommonMsg*)0;


}
 
V

Victor Bazarov

NewToCPP said:
The following change fixed the problem. Why should I type cast msg to
DerivedMsg*, does it already know that it is of type DerivedMsg* not
CommonMsg*?

Why does it work for the first element not for the subsequent ones?

Change that worked:
-----------------------------
CommonMsg* DerivedMsgQ::getElement(int index)
{
if (index < 5)
return (CommonMsg*) (&((DerivedMsg*)msg)[index]);
else
return (CommonMsg*)0;


}

An array of objects of derived class should never be treated as
an array of objects of base type. You can only do it with individual
objects. As soon as you try indexing using an "incorrect" pointer,
the compiler tries to calculate the offset in the array using the
incorrect size, and you end up with a pointer to nowhere.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,297
Messages
2,571,536
Members
48,282
Latest member
Xyprime

Latest Threads

Top