小心指针被delete两次
C++类中,有时候使用到传值调用(对象实体做参数),遇到这种情况,可要小心了!特别是当你所传值的对象生命周期较长,而非临时对象(生命周期段)的时候。来看看下面的情况:
#include <iostream>using namespace std;class Text{private: char * str;public: Text(){str = new char[20];::memset(str,0,20);} void SetText(char * str) { strcpy(this->str,str); } char * GetText() const{return str;} ~Text() { cout << "~Text Destruction" << endl; delete [] str; cout << "~Text Over" << endl; }};void Print(Text str){ cout << str.GetText() << endl;}int main(){ Text t; t.SetText("abc"); Print(t); return 1;} |
上面执行的结果程序崩溃了。原因:
Print(Text str)在对str进行复制构造的时候,没有进行深度拷贝;当 Print退出的时候,因为是临时对象(函数初始时构造),对str进行析构,此时还没有任何破绽;但回到main,继而退出main 的时候,又对t进行析构,但此时t内的str中的内容已经被销毁。由于对一内存空间实施了两次销毁,于是出现内存出错。
解决方法:
- 重写浅拷贝。像一下版本,不同的情况要作出适当的调整:
#include <iostream>usingnamespacestd;classText{private:char* str;public:Text(){str =newchar[20];::memset(str,0,20);}Text(Text &t){str =newchar[20];strcpy(str,t.GetText());}voidSetText(char* str){strcpy(this->str,str);}char* GetText()const{returnstr;}~Text(){cout <<"~Text Destruction"<< endl;delete[] str;cout <<"~Text Over"<< endl;}};voidPrint(Text str){cout << str.GetText() << endl;}intmain(){Text t;t.SetText("abc");Print(t);return1;} - (推荐)不使用传值调用。就像下面书写如下Print版本:
voidPrint(Text &str){cout << str.GetText() << endl;} - 除非对象内所有的成员读属非指针内存内容,那么谨慎使用文章前面的用法。

浙公网安备 33010602011771号