C++浅拷贝与深拷贝(程序员面试宝典试题)

来源:互联网 发布:oracle数据库中文注释 编辑:程序博客网 时间:2024/06/15 15:42
#include<iostream>#include<cstdlib>#include<vector>#include<cstring>using namespace std;class CDemo{public:CDemo():str(NULL){};~CDemo(){if(str){delete[] str;}}char *str;};int main(int argc,char** argv){CDemo d1;d1.str=new char[32];strcpy(d1.str,"trend micro");vector<CDemo>*a1=new vector<CDemo>();a1->push_back(d1);delete a1;return EXIT_SUCCESS;}

问题:找出以上程序错误的地方?(见p105-106)






分析

这个程序退出时会出问题,重复delete 同一片内存,程序崩溃。如果把析构函数改为如下,可以更清楚地看到这一点:

~CDemo(){if(str){static int i=0;cout<<"&CDemo"<<i++<<"="<<(int *)this<<",   str="<<(int *)str<<endl;delete[] str;}}

运行结果如下:


也就是说,发生了CDemo 类的两次析构,两次析构str 所指向的同一内存地址空间(两次str 值相同=0x362e18)。

本问题归根结底就是浅拷贝与深拷贝的问题。如果CDemo 类添加一个这样的复制拷贝构造函数就可以解决问题:

CDemo(const CDemo &cd){this->str=new char[strlen(cd.str)+1];strcpy(str,cd.str);}

改正之后的程序如下:

#include<iostream>#include<cstdlib>#include<vector>#include<cstring>using namespace std;class CDemo{public:CDemo():str(NULL){};CDemo(const CDemo &cd){this->str=new char[strlen(cd.str)+1];strcpy(str,cd.str);}~CDemo(){if(str){static int i=0;cout<<"&CDemo"<<i++<<"="<<(int *)this<<",   str="<<(int *)str<<endl;delete[] str;}}char *str;};int main(int argc,char** argv){CDemo d1;d1.str=new char[32];strcpy(d1.str,"trend micro");vector<CDemo>*a1=new vector<CDemo>();a1->push_back(d1);delete a1;return EXIT_SUCCESS;}
运行结果为:


添加深复制拷贝构造函数就可以解决问题了。






原创粉丝点击