c ++复制构造函数和指针

时间:2016-01-08 13:07:12

标签: c++ pointers copy-constructor delete-operator

我的课程Place有这样的方法:

class  Place{

    protected:
    Keypoint* _kp;

    Place() {
        Keypoint* kp = new Keypoint();
        _kp = kp;
    };
    Place(const Place& cSource){
        delete _kp;
        _kp = cSource.makePointer();

        }
    virtual ~Place(){
        delete _kp;
    }

    virtual Keypoint* makePointer() const {
        return _kp->makePointer();
    }


};

因此是构造函数,析构函数和复制方法。

在我的主要内容中我做了一些像AASS::graphmatch::Place ppp; AASS::graphmatch::Place p2(ppp);这样简单的事情来尝试复制构造函数,并且我有一个巨大的段错误,valgrind告诉我在复制中删除后使用Conditional jump or move depends on uninitialised value(s)。 Keypoint中的方法makePointer执行new并返回指针Keypoint*

virtual Keypoint* makePointer() const {
    Keypoint* d = new Keypoint();
    return d;
}

我的理解是,应该使用删除释放每个新内容,以便在调用makePointer之前使用delete。这就是为什么我开始删除_kp来释放旧内存然后我为它分配新创建的指针。

我无法理解为什么我有未初始化的价值?

3 个答案:

答案 0 :(得分:3)

在您的复制构造函数中,您正在调用delete _kp;。但是_kp此时尚未初始化。

这不会很好。

删除第delete _kp;行。更好的是,考虑使用基本成员初始化

Place(const Place& cSource) : _kp(cSource.makePointer())
{
}

更好的是,考虑为std::unique_ptr成员使用Keypoint之类的托管指针类。

答案 1 :(得分:3)

您编写了复制构造函数,就好像它是赋值运算符一样:

Place(const Place& cSource){
    delete _kp;
    _kp = cSource.makePointer();

    }

您可能需要一个赋值运算符,您可能还需要一个复制构造函数。但它们并不是一回事。

在进入复制构造函数时,_kp会保留垃圾,因此delete是一个错误。

答案 2 :(得分:1)

您在复制构造函数中删除未初始化的指针:

Place(const Place& cSource){
    // delete _kp; // _kp is not initialized 
    _kp = cSource.makePointer(); // now _kp gets initialized
}