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

c++ Copy constructor and pointer

我正在使用这样的方法 class 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 和 return 一个指针 Keypoint*

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

我的理解是每个新的都应该使用 delete 来释放,这就是我在调用 makePointer 之前使用 delete 的原因。所以这就是为什么我首先删除 _kp 以释放旧内存,然后将新创建的指针分配给它。

我不明白为什么我有未初始化的值?

在您的复制构造函数中,您正在调用 delete _kp;。但是 _kp 那时还没有初始化。

那不会有好下场。

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

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

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

你把你的复制构造函数写成一个赋值运算符:

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

    }

你可能需要一个赋值运算符,你可能还需要一个拷贝构造函数。但它们不是一回事。

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

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

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