我在此代码上有双重免费或损坏(fasttop)错误。我想我错过了“复制构造函数”的一些东西。
class Vector{
int taille;
int* ptr;
public:
Vector():taille(0), ptr(NULL){
...
}
Vector(int n){
...
}
//The most important one
Vector(const Vector& source){
if(source.ptr != NULL){
taille = source.taille;
ptr = new int[taille];
for(int i=0;i<taille;i++) ptr[i]=source.ptr[i];
}else{
taille=0;
ptr=NULL;
}
cout << "Copy constructor" << endl;
}
~Vector(){
if(ptr!=NULL) delete ptr;
}
};
这是测试:
int main()
{
Vector b(5);
Vector a(b);
a=Vector(12);
return 0;
}
上面的=运算符不会调用复制构造函数。为什么?
它说:“双重自由或腐败(fasttop)”
随着表达
a = Vector(12)
发生了一些事情:
Vector
对象(来自Vector(12)
)。这是使用Vector(int)
构造函数构造的。a
将临时对象分配给a.operator=(<temporary object>)
。
默认编译器生成的operator=
函数执行简单的成员分配,即它基本上执行ptr = other.ptr
。这意味着你现在有两个对象ptr
成员指向同一个内存:临时对象和a
。delete
(实际上应该是delete[]
)。
这当然意味着a.ptr
不再指向有效的内存,当它后来超出范围并被破坏时,你尝试delete
已经删除的内存。这里没有复制结构。这都是复制任务。复制构造仅用于实际构造,创建对象时(临时或非临时)。我认为你很困惑,因为=
符号可以用于复制构造,如
Vector a = b; // This is a copy-construction
// The copy-constructor of `a` is called with
// a reference to `b` as argument
// It's equal to `Vector a(b)`
这与作业非常不同
a = b; // This is a plain assignment
// It is equal to `a.operator=(b)`
崩溃是通过跟随the rules of three, five or zero之一解决的。
我还建议你阅读,例如this canonical assignment operator reference。
你正在任务Vector
中创建一个临时的a = Vector(12)
,它通过operator=
分配给a
。临时Vector
在赋值语句结束时被销毁,a
在函数结束时被销毁。两者都指向同一个已分配的数组,因为您没有定义复制赋值operator=
: