2010-06-07 22 views
2

請在這個節目有一個一目瞭然:複製構造演示(崩潰......情況2)

class CopyCon 
{ 
public: 
char *name; 

CopyCon() 
{ 
    name = new char[20];   
    name = "Hai";//_tcscpy(name,"Hai"); 
} 

CopyCon(const CopyCon &objCopyCon) 
{ 
    name = new char[_tcslen(objCopyCon.name)+1]; 
    _tcscpy(name,objCopyCon.name); 
} 

~CopyCon() 
{ 
    if(name != NULL) 
    { 
     delete[] name; 
     name = NULL; 
    } 
} 
}; 

int main() 
{ 
    CopyCon obj1; 
    CopyCon obj2(obj1); 
    cout<<obj1.name<<endl; 
    cout<<obj2.name<<endl; 
} 

這個程序崩潰的執行。錯誤:「表達式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)」

如果我使用aasignment操作符將其命名爲「Hai」,那麼它會崩潰。當我使用string func _tcscpy將「Hai」分配給名稱時,它的工作完美無缺。有人可以解釋爲什麼這樣嗎?

+0

這是一種有趣的只有10K的聲譽用戶如何發帖回答到你的問題。基本上他們都這樣說。這是否意味着在達到10k的聲譽時可以獲得更高層次的知識? – DaClown 2010-06-07 08:30:57

+0

刪除前無需檢查空值。傳遞NULL來刪除是可以的。 – 2010-06-07 08:36:13

+2

你爲什麼在'char'數組中使用'_tcslen'和'_tcscpy'? – 2010-06-07 09:00:48

回答

3

在默認的構造函數

CopyCon() 
{ 
    name = new char[20];   
    name = "Hai";//_tcscpy(name,"Hai"); 
} 

你分配一個字符串的指針,並調用delete[]它的析構函數的地址,這是不確定的行爲。只應在由new[]返回的地址上調用delete[]

當您改爲使用_tcscpy()時,將文字內容複製到由new[]分配的緩衝區中,然後析構函數正常運行。

2

當您使用賦值時,您將指針name指向字符串文字「Hai」。這後來在析構函數中被刪除。然而,字符串文字沒有被分配到new,並且不能像這樣被刪除,所以你得到了未定義的行爲。您只能用delete取消分配您分配給new的東西。這與複製構造函數無關。

4
name = "Hai";//_tcscpy(name,"Hai"); 

你是不是抄襲「海」的內容爲name,如果你試圖刪除名字後來則威力崩潰,而不是name將指向一個只讀存儲器(其內容是「海」) 。

+0

這裏沒有更多的要說。 – fmuecke 2010-06-07 08:24:07

+0

除了C++不保證「Hai」存儲在只讀存儲器中。 – 2010-06-07 08:26:12

+1

它保證調用delete []對字符串文字結果uin未定義的行爲。 – 2010-06-07 08:52:05

0

你在那段代碼中做的是你爲名字分配一個內存塊(給名字指針分配一個地址)。然後你實際上用字符串文字「Hai」的地址覆蓋這個地址(在構造函數完成之後,它不再存在)。這就是爲什麼你會得到錯誤,因爲析構函數試圖釋放不屬於你的內存。 (你沒有分配它)。

2
name = new char[20];   
name = "Hai";//_tcscpy(name,"Hai"); 

在這裏,你是不是複製數據成new分配的內存。相反,您要爲指向只讀位置(大多數情況下)的指針name指定一個新值。由於此存儲器未使用new進行分配,因此您無法對其執行delete。另外請注意,由於使用new char[20];分配的內存不會被刪除,因此您在此處有內存泄漏。

2

非常相同的程序,但在C++:

struct CopyCon 
{ 
    CopyCon(): name("HAI") {} 
    std::string name; 
}; 

int main(int argc, char* argv[]) 
{ 
    CopyCon obj1; 
    CopyCon obj2(obj1); 
    cout<<obj1.name<<endl; 
    cout<<obj2.name<<endl; 
} 

防雷工程,是清楚的,我打字比你少;)

+0

用於顯示「真實」C++的+1。 – xtofl 2010-06-07 09:13:56