为什么这段代码挂在上面提到的地方?

时间:2011-09-12 15:38:35

标签: c++ operator-overloading

这是我编写的用于研究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。

5 个答案:

答案 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=并不能确保您有足够的空间来容纳完整的字符串,这意味着您可能会触发未定义的行为。