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

时间:2018-01-03 21:05:31

标签: c++ pointers

我在此代码上有双重免费或损坏(fasttop)错误。 我想我错过了#34;复制构造函数"。

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;
}

上面的=运算符不会调用复制构造函数。为什么?

它说:&#34;双重免费或腐败(快速顶部)&#34;

2 个答案:

答案 0 :(得分: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已经删除的内存。

    < / LI>

    这里有 no 复制构造。这都是复制任务。复制构造仅用于实际构造,创建对象时(临时或非临时)。我认为你很困惑,因为=符号可用于复制构造,如

    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

答案 1 :(得分:0)

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

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