拷贝构造函数相关

下面一段程序退出时会出现错误吗(摘自面试宝典)?

#include<iostream>
using namespace std;

class CDemo {
public:
    CDemo() :str(nullptr) {};
    ~CDemo()
    {
        if (str)    delete [] str;        
    };
    char* str;
};

int main()
{
    CDemo d1;
    d1.str = new char[32];

    vector<CDemo>* a1 = new vector<CDemo>();

    a1->push_back(d1);

    delete a1;

    return 0;
}

退出时会出现重复 delete 同一片内存,程序崩溃。首先

vector<CDemo>* a1 = new vector<CDemo>(); 指定一个指针,指向 vector<CDemo>,并用 new 操作符进行了初始化,所以必须在适当的时候释放 a1 所占有的内存空间,因此调用 "delete a1" 这句是正确的。

但是为什么会释放同一片内存两次呢?

在执行 “a1->push_back(d1);” 这条语句时,会调用 CDemo 的拷贝构造函数,现在 CDemo 没有定义拷贝构造函数,但是编译器会为 CDemo 类自动构建一个默认的拷贝构造函数(浅拷贝)。

执行“a1->push_back(d1);”后,a1 里面的 CDemo 元素与 d1 里面的是不同的对象,但是 a1 里 CDemo 元素的 str 与 d1.str 指向的却是同一块内存。

而局部变量 CDemo d1 在 main 函数退出时,自动释放所占有的内存空间,此时会自动调用 CDemo 的析构函数,问题就出现在这里。前面 delete a1 已经把 d1.str 释放了,main 函数退出时,又要释放已经释放的 d1.str 内存空间,所以程序最后崩溃。

 

此题归根结底是浅拷贝与深拷贝的问题,如果 CDemo 类添加一个如下的拷贝构造函数就没有问题了:

CDemo(const CDemo& cd){

    this->str = new char[strlen(cd.str) + 1];

    strcpy(str, cd.str);

}

 

 

转载于:https://my.oschina.net/u/3349205/blog/1113973

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值