C++編程當心指針被delete兩次。本站提示廣大學習愛好者:(C++編程當心指針被delete兩次)文章只能為提供參考,不一定能成為您想要的結果。以下是C++編程當心指針被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>
using namespace std;
class Text
{
private:
char * str;
public:
Text(){str = new char[20];::memset(str,0,20);}
Text(Text &t)
{
str = new char[20];
strcpy(str,t.GetText());
}
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版本:
void Print(Text &str)
{
cout << str.GetText() << endl;
}
除非對象內一切的成員讀屬非指針內存內容,那末謹嚴應用文章後面提到的用法。