2011-12-06 83 views
1

更新:對於STR1的新數據分配的內存。仍然是內存錯誤。重寫+ =操作員C++

我試圖改寫爲我創建了一個字符串類+ =方法。

Class mystring{ 

public: 
    friend void operator+=(mystring& str1, const mystring& str2){ 
     mystring temp; 

     delete[] temp.data; 
     temp.length = str1.length + str2.length; 
     temp.data = new char[temp.length + 1]; 

     strcpy(temp.data, str1.data); 
     strcat(temp.data, str2.data); 

     delete[] str1.data; 
     str1.length = temp.length; 

     strcpy(str1.data, temp.data); 

    } 

private: 
    char *data; 
    int length; 

} 

然後在主類:

mystring str1("hi"); 
mystring str2("matt"); 

str1 += str2; 
cout << str1 << endl; 

此功能工作,因爲它應該的,但我得到的內存錯誤,當我運行的valgrind全部結束。我無法弄清楚爲什麼。如果有人可以給我任何提示,這將是非常棒的。

感謝

+0

你爲什麼要重新發明輪子呢? – SLaks

+1

請將相關錯誤顯示在valgrind中以及您的構造函數代碼中。 – Arunmu

+0

請注意,您應該定義一個交換方法。你應該有一個特殊的mystring構造函數,所以你不必先刪除temp.data。你應該使用memcpy,因爲你知道長度:strcpy和cat是浪費的。使用temp之後的交換方法,您可以交換新的字符串(* this,temp)。交換隻是交換指針和長度。 –

回答

2

首先,你的意思是不是:

strcat(str1.data, str1.data); 

但:

strcat(str1.data, str2.data); 

其次,如果你希望str2.data去?這是一個記憶塗鴉,因此valgrind錯誤。驚訝它不只是崩潰。

您需要重新分配足夠的存儲空間的組合長度,複製在兩個原始字符串和免費str1.data其重新分配給新的存儲之前。

基於更新後:

friend void operator+=(mystring& str1, const mystring& str2) 
    { 
     // Not using a temp mystring here, as the temp never really maintains its state as a mystring 
     // I am assuming length is the length of the string, not the storage. Not the best design if you consider resizing the the string to less than the storage 
     int newStringLength = str1.length + str2.length; 
     char* newStorage = new char[newStringLength + 1]; 

     strcpy(newStorage, str1.data); 
     // strcat has to scan from the start of the string; we do not need to. 
     strcpy(newStorage + str1.length, str2.data); 

     delete[] str1.data; 

     str1.length = newStringLength ; 
     str1.data = newStorage; 

     // Haven't though about the case where str2 is an alias for str1. 
    } 
+0

感謝您的回覆。我改變了我的代碼以嘗試使用你的方法,但它仍然給我內存錯誤。 OP已更新。 – KWJ2104

+0

「有沒有關於str2是str1的別名的情況。」 - 如果你做's + s',爲什麼會出錯? 's'只是包含了現在重複兩次的原始字符串。 – visitor

+0

@visitor。沒有想過,意味着它的價值檢查。現在快速閱讀向我建議,這將是好的 - 但我可以很容易地想到替代實現,只會打破別名情況。 – Keith

2

您需要在str1分配更多的內存。

你不能只是盲目照搬過去的數組的末尾。

1

你必須分配堆持有字符和釋放堆時不再需要它。

事情是這樣的:

data=new char[length+1]; 
1
//it is strange that operator += return void 
// usually we have T& operator += (T const&, T const&) 
    //or T& T::operator +=(T const&) 
friend void operator+=(mystring& str1, const mystring& str2){ 
    //make sure str1 and str2 are correclty initialzed 
    str1.length = str1.length + str2.length; 
    //make sure str1.data has enough memory to hold all the data 
    //make sure str1.data and str2.data are null terminated strings, not binary data 
    strcat(str1.data, str2.data); 
}