C++ 一不小心被delete兩次


2012-09-11 18:04:看到園里朋友們這么熱心,有那么一會心里好興奮。:)

2012-09-11 下午:本文曾出現很嚴重的錯誤,但不要緊,感謝園友們的即使指正。

不喜歡程序語言的

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中的內容已經被銷毀。由於對一內存空間實施了兩次銷毀,於是出現內存出錯。

解決方法:

  1. 重寫淺拷貝。像一下版本,不同的情況要作出適當的調整:
    #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;
    }
  2. (推薦)不使用傳值調用。就像下面書寫如下Print版本:
    void Print(Text &str)
    {
    	cout << str.GetText() << endl;
    }
  3. 評論中的小伙伴還提供了一個方法,很值得推薦,同時這也是編程良好的習慣:指針在使用的時候需要作空判斷,在刪除指針時候需要置空。

后記——語言的探討

C++,以至於其他的程序語言,都是偉大的創造。他們是規則的世界,一愣一腳皆規則。當對某一規則有所熟知之后,就似發現新大陸似的。但想想,這些規則可經不起碰撞打擊,殃及的是coder,是我們。這些規則不像1+1=2,“三點定面”來的鐵定,總之比起數學理論來說,似乎程序規則脆弱很多,總之在它們身上看到的價值是有限的,總我還是選擇了計算機...為之奈何,不得而知。

本文完 2012-09-11

搗亂小子 http://www.daoluan.net/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM