C ++拷贝构造函数上的双重自由错误

问题描述 投票:0回答:2

我在此代码上有双重免费或损坏(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)”

c++ pointers
2个回答
4
投票

随着表达

a = Vector(12)

发生了一些事情:

  1. 首先创建一个新的临时Vector对象(来自Vector(12))。这是使用Vector(int)构造函数构造的。
  2. 使用a将临时对象分配给a.operator=(<temporary object>)。 默认编译器生成的operator=函数执行简单的成员分配,即它基本上执行ptr = other.ptr。这意味着你现在有两个对象ptr成员指向同一个内存:临时对象和a
  3. 分配完成后,临时对象将被销毁。这意味着该对象占用的内存被传递给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


0
投票

你正在任务Vector中创建一个临时的a = Vector(12),它通过operator=分配给a。临时Vector在赋值语句结束时被销毁,a在函数结束时被销毁。两者都指向同一个已分配的数组,因为您没有定义复制赋值operator=

http://www.cplusplus.com/doc/tutorial/operators/

© www.soinside.com 2019 - 2024. All rights reserved.