c ++类阵列的神秘转移

时间:2011-05-21 14:18:59

标签: c++ memory dynamic parameters transfer

class Array
{
    double *mx; int mn;
public:

 Array();
~Array(){delete []mx};
 Array& operator-(Array& b);  //first right way
 Array operator -(Array b);  //wrong way, but I don't understand why
};

Array::Array ()
{ 
  mn=10;
  mx=new double[mn];
}

//first, works perfectly
Array& Array::operator -(Array& b)
{
    int i=0;

    for(i=0;i<mn ;i++)
       this->mx[i]-=b.mx[i];

  return *this;
 }


// here is Error

Array Array::operator -(Array b)
{ 
    int i=0;

    for(i=0;i<mn ;i++)
       this->mx[i]-=b.mx[i];

  }


int main() {
   Array x,b;
   x=x-b;
}

如果我使用第一次重载,一切正常。

但是,如果我使用第二个,所有编译都很好,但是当程序执行时,我会收到很多这样的错误:

"c++ ** glibc detected *** double free or corruption" 

http://s41.radikal.ru/i091/1105/e1/2349397c04a2.png

我无法弄清楚为什么会这样。

据我所知,当我调用Array Array::operator-(Array b)时,必须复制该对象,并且一切都必须正常,但是有错误。

我已经读过,我要对象分配在内存中的同一个地方。但我试过这样做:

        Array Array::operator +(Array b)
 { Array c;
 int i=0;
 for(i=0;i<mn;i++) 
this->mx[i]+=b.mx[i];
 cout<<&this->mx<<" "<<&b.mx<<endl; 
exit(0);
 return c; }

我希望在内存中收到相同的地址....

答案是0xbfb45188 0xbfb45178为什么它们相等?

[p> furhermore,当我在这里声明类的名称(A对象)
  编译器必须为对象提供堆栈中的新内存    我哪里错了?我不明白....

3 个答案:

答案 0 :(得分:3)

Array Array::operator -(Array b)

此行将创建数组的副本。由于您没有复制构造函数,编译器将只复制所有字段,包括指针字段“mx”。现在,您有两个对象都指向相同的已分配内存。当每个被破坏时,将调用delete [] ....

您需要编写复制构造函数或确保不进行复制。 要做到这一点通过引用传递

Array Array::operator -(Array& b)

(这应该也是const ......但这是一个不同的问题)

答案 1 :(得分:3)

您违反了rule of three

答案 2 :(得分:1)

  • operator- 参考,否则您将执行不必要的副本。但是,它不需要。它当然应该返回一个值,因为-在语义上为您提供了一个新对象。当您撰写c = a-b时,您不希望ab更改。
  • 如上所述,您不需要 来引用operator-,在第二个示例中,您可以按值获取。这没关系,除了你有第二个bug:
    • 您的Array类有一个内部缓冲区,new正在构建,delete在它被销毁(~Array)时。
    • 但是,具有用户定义的复制构造函数,并且不会自动为您复制缓冲区;只复制指针mx
    • 因此,当您复制Array时,您现在有两个对象,指针mx指向同一个缓冲区。当一个副本超出范围时,该缓冲区为delete d;一段时间后,另一个副本试图做同样的事情,delete两次使用相同的缓冲区是一个错误。

我的建议:

  • 将复制构造函数和operator=写入班级Array。非常重要。
  • 无论如何都要operator-参考。这更有意义。

希望有所帮助。