管理unique_ptr的向量的正确方法是什么?

时间:2017-07-31 19:31:27

标签: c++11 segmentation-fault unique-ptr

如果我有一个管理std::unique_ptr的向量的类,那么管理这个资源的正确方法是什么?我有一个最低限度的工作示例。但是,在运行此代码时,会发生分段错误。我想这是因为main引用了bin std::moveAContainer::addValue,但我不确定,我不知道如何测试这个假设。

#include <memory>
#include <vector>
#include <iostream>

class AnotherContainer;

class AContainer{
    public:
        void addValue(AnotherContainer& anInt);
        const std::vector<std::unique_ptr<AnotherContainer>>& getVals() const;
    private:
        std::vector<std::unique_ptr<AnotherContainer>> ints;
};

void AContainer::addValue(AnotherContainer& anInt){
    ints.push_back(std::move(std::unique_ptr<AnotherContainer>(&anInt)));
}

const std::vector<std::unique_ptr<AnotherContainer>>& AContainer::getVals() const{
    return ints;
}

class AnotherContainer{
    public:
        AnotherContainer(int val) : myVal(val){};
        int getVal() const{
            return myVal;
        }
    private:
        int myVal;
};

int main(){
    AContainer bin;
    AnotherContainer val1(1), val2(2);
    bin.addValue(val1);
    bin.addValue(val2);
    const std::vector<std::unique_ptr<AnotherContainer>>& vals = bin.getVals();
    std::cout << "vals[0] = " << vals[0]->getVal() << std::endl;
    return 0;
}

1 个答案:

答案 0 :(得分:2)

发生的事情是你在堆栈上创建两个AContainer实例:

AnotherContainer val1(1), val2(2);

然后在addValue调用中将指针包装到这些引用:

bin.addValue(val1);
bin.addValue(val2);

所以,当对main函数的调用返回时,在堆栈上创建的对象val1和val2被删除,但在删除bin时也被删除,因为智能指针调用它们包装的对象上的析构函数,从而导致分段错误。

智能指针用于管理堆上的内存,使用new运算符分配,因此为了使事情顺利运行,您应该以这种方式初始化val1和val2:

AnotherContainer* val1 = new AnotherContainer(1);
AnotherContainer* val2 = new AnotherContainer(2);

(您还必须对您的方法进行一些更改以便编译程序)