程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++編程當心指針被delete兩次

C++編程當心指針被delete兩次

編輯:關於C++

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;
}

除非對象內一切的成員讀屬非指針內存內容,那末謹嚴應用文章後面提到的用法。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved