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; }
除非對象內一切的成員讀屬非指針內存內容,那末謹嚴應用文章後面提到的用法。