为什么这段代码会在提到的地方崩溃? [英] Why does this code crash at the places mentioned?

查看:50
本文介绍了为什么这段代码会在提到的地方崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你能详细说明为什么这段代码在提到的地方崩溃吗?我有点难住了.我猜这与 sizeof(int) 有关系,但我不太确定.谁能解释一下?

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;
}

推荐答案

引自此常见问题解答:派生数组和基数组一样吗?

Derived 比 Base 大,用第二个对象 baseArray 做的指针运算是不正确:编译器在计算地址时使用 sizeof(Base)对于第二个对象,但数组是派生数组,这意味着计算出的地址(以及随后的成员函数 f()) 甚至不在任何对象的开头!它的打在派生对象的中间.

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.

这篇关于为什么这段代码会在提到的地方崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆