这是我编写的用于研究C ++运算符重载的一个简单例子。当我执行它时,代码挂起在语句c = a + b;和控制永远不会达到c.display();
作为调试的一部分,如果我在赋值运算符重载函数中放置cout << ptr << '\n';
,它会打印出HelloWorld,因此字符串似乎没有格式错误。
为什么它会挂起?我错过了什么?
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 Express / Windows。
答案 0 :(得分:1)
您的operator=
已损坏。在执行strcpy
之前,您没有正确分配足够的(或任何)内存。这导致了不确定的行为。
答案 1 :(得分:1)
char * str = new char [strlen(ptr)+ strlen(s.ptr)+ 1]; //释放此内存的位置
析构函数释放内存。
在运算符=您必须释放已分配的内存并再次分配
答案 2 :(得分:1)
我认为你得到的是内存错误。这一行:
c = a + b;
执行以下操作:
c.constructor()
c.operator=(a.operator+(b));
并且您的operator =无法分配内存
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);
}
答案 3 :(得分:0)
operator =应释放旧缓冲区,然后像在构造函数中那样分配一个新缓冲区。
答案 4 :(得分:0)
代码似乎没有任何明显的问题会在点击c.display()
之前阻止它,但它可能看起来就像它正在这样做。
操作cout << ptr << '\n';
不会刷新流,这意味着输出可能会被缓存到以后的时间。可能是整个程序基本已完成并等待用户在getchar()
中输入字符的情况。
尝试在调试器中运行代码或将输出更改为cout << ptr << endl;
。
顺便说一句:你在operator+
泄漏记忆,应该照顾它。我知道你已经问过如何做到这一点,你可能不喜欢(或理解)所提出的解决方案,但保留它并不是解决方案。
operator=
并不能确保您有足够的空间来容纳完整的字符串,这意味着您可能会触发未定义的行为。