2011-09-12 40 views
0

這是一個天真的例子,我編碼研究C++操作符重載。當我執行它時,代碼掛在語句c = a + b;和控制從未達到c.display();爲什麼這個代碼掛在提到的地方?

隨着調試的一部分,如果我在賦值操作符重載函數它打印出的HelloWorld放cout << ptr << '\n';,所以串似乎並不爲畸形。

爲什麼它掛起呢?我在想什麼?

class mystring 
{ 
    char *ptr; 

    public: 

    mystring(char *str = "") 
    { 
     ptr = new char[strlen(str) + 1]; 
     strcpy(ptr,str); 

    } 

    mystring operator +(mystring s) 
    { 
     char *str = new char[strlen(ptr) + strlen(s.ptr) + 1];//where should this memory be freed 
     strcpy(str,ptr); 
     strcat(str,s.ptr); 
     return mystring(str); 
    } 

    void operator =(mystring s) 
    { 
     strcpy(ptr,s.ptr); 

     //cout << ptr << '\n'; \\Debug - this prints out HelloWorld but still hangs 
    } 

    void display() 
    { 
     cout << ptr << '\n'; 
    } 

    ~mystring() 
    { 
     delete [] ptr; 
    } 
}; 

int main() 
{ 
    mystring a="Hello",b="World",c; 

    c = a + b; 

    c.display(); 

    getchar(); 

} 

編輯:編譯器:MS-的Visual C++ 2010速成/ Windows的。

+0

'運營商= '不分配內存。 'operator +'導致分配兩次。 –

+0

我也想補充一點,你應該實現一個合適的拷貝構造函數... – Nim

+0

像valgrind這樣的內存分析器會發現這種內存錯誤,使用一個。 – Francois

回答

1

我認爲你得到的是內存錯誤。這條線:

c = a + b; 

執行以下操作:

c.constructor() 
c.operator=(a.operator+(b)); 

和您的運營商=內存分配失敗

void operator =(mystring s) 
{ 
    // ptr is allocated enough memory for "", i.e. one byte 
    strcpy(ptr,s.ptr); // copying more than one byte into one byte array 
    //cout << ptr << '\n'; // this works, but you've trashed memory with the strcpy 
} // stack might be corrupted here, depends where this is, so execution can end up anywhere 

你需要的是:

void operator = (mystring &s) // reference! 
{ 
    delete [] ptr; 
    ptr = new char [strlen (s.ptr + 1)]; 
    strcpy (ptr, s.ptr); 
} 
+1

或者'tempPtr = new char [strlen(s.ptr + 1)]; strcpy(tempPtr,s.ptr); swap(ptr,tempPtr);刪除tempPtr;'提供[強大的例外保證](http://en.wikipedia.org/wiki/Exception_guarantees)。 –

+0

@Skizz - 謝謝。它的工作原理,但只有當我註釋析構函數中的刪除ptr。任何想法whyc可能會發生。是因爲ptr已經在operator =()中被釋放/刪除了嗎?那麼是什麼修復。 – goldenmean

+0

@goldenmean:這可能是因爲你在某處複製了'ptr'的值而不是複製字符串。你的'operator +'通過值返回結果,以便複製和刪除,所以'ptr'被刪除兩次。嘗試添加與'operator ='相同的'mystring(const mystring&source)'結構。你應該在刪除它後將'ptr'設置爲'0',這樣再次刪除它不會引起問題。 – Skizz

1

您的operator=已損壞。在執行strcpy之前,您沒有正確分配足夠的(或任何)內存。這導致未定義的行爲。

1

字符*海峽=新的char [strlen的(PTR)+的strlen(s.ptr)+ 1]; //應該在哪裏這個存儲器被釋放

存儲器上除去析。

在運營商=你必須釋放分配的內存,然後重新分配

+1

不是真的 - 您突出顯示的特定行在'operator +'中,因此必須在該函數中進行清理。第二點是正確的,但... – Nim

+0

對不起,我的錯。當然,這個方法應該釋放內存。 – Ilmirus

0

運營商=應釋放舊緩衝區,然後分配一個新的像你在構造函數中做。

0

該代碼似乎沒有任何明顯的問題,會使它在打c.display()之前被阻止,但它可能看起來像它這樣做。

操作cout << ptr << '\n';不刷新流,這意味着輸出可能會被緩存,直到以後的時間。可能是整個程序已經完成基本上並且正在等待用戶輸入getchar()中的字符。

嘗試在調試器中運行代碼或將輸出更改爲cout << ptr << endl;

順便說一句:你正在泄漏內存operator+,並應該照顧它。我知道你已經問過如何做到這一點,你可能不喜歡(或理解)提出的解決方案,但如果沒有解決方案就不行。

operator=不能確保您有足夠的空間容納完整的字符串,這意味着您可能會觸發未定義的行爲。