不要用多态方式处理数组以及数组的析构

今天Jackxu贴了一段代码说有一个奇怪的崩溃,希望一起看看,于是一研究了一下,代码如下,coredump崩溃的地方在delete,编译器是gcc 4.1.2版本。同时在visual studio 上,这个没有错误。崩溃前也没有任何输出。

#include<stdio.h>

class Base

{   

    char sz[12];

    public:   

    virtual ~Base()       

    {

        printf("Base::~Base/n");       

    }

};

 

class Parent: public Base{   

    bool c;

    public:   

     ~ Parent ()       

    {

       printf("Parent::~Parent /n");       

    }

};

 

int main()

{  

    Base* p = new test[2];   

 

    delete[] p;

    return 0;

}

 

初看了半天没有发现问题。后来贴到群里,让大家看。几个小伙子提醒是Base* p = new test[2];   导致的问题,我居然想了半天为啥不准这样用呢。(快一年没有写C++代码了,反映有点迟钝,丢人显眼了)。

经过多方提醒,才突然想起了这样的base类的指针在++处理过程中应该是有问题的,因为指针无法知道自己应该塑形成子类指针,结构就会导致delete 了一个无效的地址,导致崩溃。其实More Effective C++对这个问题是有说明的。详见条款3,不要用多态处理数组。C++语言规格说,通过base类指针删除一个由dreived class 对象构成的数组,结果未定义。

反馈给Jack,Jack又提出如果delete第二个位置的指针导致崩溃,为啥一行打印信息没有输出,回头看看代码发现,的确是,如果第一个变量已经析构,那么就应该Base::~Base 就应该得到输出呀。Sriver用代码输出给出了析构顺序,发现数组是从后面开始调用析构函数的。先以为这个是编译器自己的实现导致的,google了一下,发现这个倒是C++标准,数组构造函数调用的时候顺序调用,析构的时候,反向调用。由于GCC的实现,Base指针指向的数组最后一个位置就是错误的,所以还没有任何输出就崩溃了。

 

感谢yunfeiyang, liangfeng , sriverxiao, kliu , djiang等同事,每次C++的多态析构总能让我栽跟头,而且很多事情只有在栽了跟头才回真正记得牢。

 

2011年3月31日星期四,又开始回头看点技术的东西

 

【本文作者是fullsail(雁渡寒潭),本着自由的精神,你可以在无盈利的情况完整转载此文档,转载时请附上BLOG链接:http://blog.csdn.net/fullsail,否则每字一元不讲价。对Baidu文库加价一倍】

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值