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"
我无法弄清楚为什么会这样。
据我所知,当我调用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对象)答案 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
时,您不希望a
或b
更改。operator-
,在第二个示例中,您可以按值获取。这没关系,除了你有第二个bug:Array
类有一个内部缓冲区,new
正在构建,delete
在它被销毁(~Array
)时。mx
。Array
时,您现在有两个对象,指针mx
指向同一个缓冲区。当一个副本超出范围时,该缓冲区为delete
d;一段时间后,另一个副本试图做同样的事情,delete
两次使用相同的缓冲区是一个错误。我的建议:
operator=
写入班级Array
。非常重要。operator-
参考。这更有意义。希望有所帮助。