这个运算符重载代码有什么问题?

时间:2015-07-01 00:31:52

标签: c++ debugging

这个c ++代码有什么问题?

它编译,但是,它不会运行。

    #include <iostream>

using namespace std;

class MyClass
{
private:
    int *x;
    int *y;
public: 
    MyClass()
    {
        x = new int[1]; *x = 0;
        y = new int[1]; *y = 0;
    }
    ~MyClass()
    {
        if(x != NULL)
        {
            delete [] x;
            x = NULL;
        }
        if(y != NULL)
        { 
            delete [] y;
            y = NULL;
        }
    }
    MyClass operator=(MyClass & rhs)
    {
        MyClass temp;
        temp.Set(rhs.x[0], rhs.y[0]);
        return temp;
    }
    void Set(int a, int b)
    {
        if(x != NULL)
        {           
            *x = a;
        }
        if(y != NULL)
        {           
            *y = b;
        }
    }
    void Show()
    {
        cout<<x[0]<<y[0]<<endl;
    }
};

int main()
{
    MyClass o1;
    o1.Set(10, 20);
    o1.Show();

    MyClass o2;
    o2 = o1;
    o2.Show();
}

enter image description here

2 个答案:

答案 0 :(得分:4)

我能看到的唯一明显错误是您将xy分配为数组,因此您需要使用delete [] x;代替delete x;,并且y。断言似乎也表明它在删除期间抛出,因为断言消息中提到的文件是dbgdel.cpp,并且它正在检查块类型是否有效(最有可能的是,它检查是否要删除块)实际上是一个数组块或单个实例)

你也不需要对NULL进行检查; new总是成功或抛出异常。

更多信息:delete vs delete[] operators in C++

编辑:此外,您还需要定义复制构造函数。请参阅rule of three

答案 1 :(得分:4)

虽然实际崩溃可能是由于rlbond的答案所提到的阵列的不匹配重新分配造成的,但还有另一个更微妙的选择:

operator=返回一个副本(不是传统的引用),它使用默认的复制构造函数创建。在此示例中,未使用它,因此创建临时。临时值xy指向与副本相同的内存,因为未定义复制构造函数。当临时被销毁时,其xy被删除 - 之后o2被销毁,导致相同的内存被解除分配两次。

值得注意的是,这堂课还有很多可能出错的地方,需要一些进一步的爱和关注。另外值得一看的是我们如何找到这个错误。

这是我通过pc-lint online linter推送的内容。 请注意,这包括导致崩溃的问题,以及许多其他需要修复的问题。

 1  #include <iostream>
 2  
 3  using namespace std;
 4  
 5  class MyClass
 6  {
 7  private:
 8      int *x;
 9      int *y;
10  public: 
11      MyClass()
12      {
13          x = new int[1]; *x = 0;
14          y = new int[1]; *y = 0;
15      }
16      ~MyClass()
17      {
18          if(x != NULL)
19          {
20              delete x;
21              x = NULL;
22          }
23          if(y != NULL)
24          { 
25              delete y;
26              y = NULL;
27          }
28      }
29      MyClass operator=(MyClass & rhs)
        _
30      {

diy.cpp 30 Info 1722:类'MyClass'的赋值运算符不返回对类的引用

diy.cpp 30信息1720:类'MyClass'的赋值运算符具有非const参数

31          MyClass temp;
32          temp.Set(rhs.x[0], rhs.y[0]);
33          return temp;
34      }
35      void Set(int a, int b)
36      {
37          if(x != NULL)
38          {           
39              *x = a;
40          }
41          if(y != NULL)
42          {           
43              *y = b;
44          }
45      }
46      void Show()
47      {
48          cout<<x[0]<<y[0]<<endl;
49      }
                _
13          x = new int[1]; *x = 0;

diy.cpp 13 Info 1733:类'MyClass'的构造函数中没有复制构造函数的新东西

20              delete x;

diy.cpp 20警告424:“新[]”数据的不当取消分配(删除)

25              delete y;

diy.cpp 25警告424:“新[]”数据的不当取消分配(删除)

33          return temp;

diy.cpp 33信息1772:赋值运算符'MyClass :: operator =(MyClass&amp;)'没有返回* this

34      }

diy.cpp 34警告1529:符号'MyClass :: operator =(MyClass&amp;)'没有先检查是否已分配给

diy.cpp 34 Info 1764:引用参数'rhs'(第29行)可以声明为const ref

diy.cpp 34警告1539:成员'MyClass :: x'(第8行)未由赋值运算符分配

diy.cpp 34警告1539:成员'MyClass :: y'(第9行)未由赋值运算符指定

48          cout<<x[0]<<y[0]<<endl;

diy.cpp 48警告613:在运算符'['[参考:文件diy.cpp:第37行]的左参数中可能使用空指针'MyClass :: x'

diy.cpp 48警告613:在运算符'['[参考:文件diy.cpp:第41行]的左参数中可能使用空指针'MyClass :: y'

49      }

diy.cpp 49信息1762:成员函数'MyClass :: Show(void)'可以成为const

50  };
51  
52  int main()
53  {
54      MyClass o1;
55      o1.Set(10, 20);
56      o1.Show();
57  
58      MyClass o2;
59      o2 = o1;
60      o2.Show();
61  }
62