C++通过基类指针delete派生类数组,析构函数是虚函数,程序为什么会崩溃? https://www.zhihu.com/question/30838092/answer/49623765

https://www.zhihu.com/question/30838092/answer/49623765

代码如下
#include<iostream>
using namespace std;

class base{
public:
    virtual ~base(){}
};

class derived:public base{
    int a;
};

int main(){
    base *p=new derived[10];
    delete[] p;
    return 0;
}
举报
7 条评论 
分享
更多回答
vczh ,专业造轮子,gaclib.net

在某些实现里,base4个字节,derived8个字节,你new了一个80个字节的derived*数组然后当base*干掉,那么要么它就会执行析构函数20次然而有10个this指针式不对的,要么他会执行10次然而有5个this指针是不对的。自然要挂。


然而在VC++下面却没问题,因为VC++的实现是记录了array的个数和每个对象的大小,他不会因为你把数组搞成了base*就真的以为他是base[],所以会执行10次析构函数,10次的this指针都对。


为什么错误的this指针就会挂呢?因为从base调用derived::~derived函数的方法,是先把一个固定的数字加到this指针上面得到一个全局的代表derived在base上面的虚函数表,然后再虚函数表里面找到析构函数的指针,最后执行它。如果你的this有问题,那中间有一步就会dereference失败,自然AV。

不明觉屌啊……
2015-06-01     
执行10次但是有5个this指针是不对的,为什么啊?
2015-06-01     
这么正经的回答居然没几个人评论。。。
2015-06-01     
尤不二  回复  何磊
执行10次的情况是:删除了10个4byte,每两个4byte指向的是正确的derived,自然有一半的this是错的
2015-06-01     
fx991ESplus  回复  何磊
sizeof(base)是4,sizeof(derived)是8呗
2015-06-01     
某些实现,话里有话啊
2015-06-01     
何磊  回复  尤不二
懂了,谢谢
2015-06-01     
还是vc的扩展厉害
2015-06-01     
轮子哥一正经起来我就看不懂了
2015-06-01     
0.0轮子哥貌似很推崇VC++
2015-06-01     
fx991ESplus  回复  莫惜培
g++……
2015-06-01     
不信linux环境下会有问题
2015-06-01     
vczh (作者)  回复  汪堇年
呵呵
2015-06-01     
学习了
2015-06-01     
仅就这个特例来说,后十次,编译器应该是call十次base::~base并压入“错误”的this(实际也没太错),然后dtor里面也没碰this,为啥还会crash?
2015-06-02     
vczh (作者)  回复  周翀
因为dtor是虚函数
2015-06-02     
周翀  回复  vczh (作者)
……哦,靠!(逃……
2015-06-02     
只是, msvc的实现的是对标准的扩充, 方言特性不具备移植性
2015-06-02     
Warthog  回复  柯基屁
这是C++的基础知识啊
2015-06-02     
汪堇年  回复  vczh (作者)
挂一下代码吧
2015-06-02     
Warthog  回复  柯基屁
果然他的脑残粉不会写代码的比会写代码的多一个数量级。。
2015-06-02     
Warthog  回复  柯基屁
因为就是脑残粉啊
2015-06-02     
虽然一句也看不懂,依然要点赞。
2015-06-02     
Warthog  回复  柯基屁
I don't give a fuck
2015-06-02     
一个都看不懂
2015-06-03     
“然而在VC++下面却没问题”
2015-06-03     
刚试了下,g++ 5.1.0 不行,clang++ 3.5.0 没出现问题。
2015-06-03  回复   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值