2011-12-06 65 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); 
}