2017-07-31 9 views
0

std::unique_ptrのベクトルを管理しているクラスがある場合、このリソースを管理する適切な方法は何ですか?私は以下の最小の実例を持っています。ただし、このコードを実行すると、セグメンテーションフォルトが発生します。これはmainbinへの参照がstd::movedのAContainer::addValueにありますが、わかりません。その仮定をどのようにテストするのか分かりません。呼び出しunique_ptrのベクトルを管理する適切な方法は何ですか?

AnotherContainer val1(1), val2(2); 

をしてから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; 
} 

答えて

2

何が起こっていることは、あなたがここにスタック上aContainerに2つのインスタンスを作成しているということです

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

したがって、メイン関数の呼び出しが返ってくると、スタック上に作成されたオブジェクトval1とval2が削除されますが、スマートポインタがデストラクタを呼び出すため、binの削除時にも削除されますそれらがラッピングするオブジェクト上に存在するため、セグメンテーションフォルトが発生します。物事がスムーズに実行するためのよう

スマートポインタを使用すると、val1とval2のこの方法を初期化する必要があり、ヒープ上にメモリを管理するために作られた新しい演算子で割り当てられている:

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

(あなたも加える必要がありますプログラムのコンパイル方法の変更)

+0

これは機能しました。私は「スタック」と「ヒープ」について読まなければならないでしょう。また、私のメソッドを変更する必要はなく、単に 'bin.addValue(* val1)'を呼び出してメソッドをそのまま保つことができます。ありがとうございました! – wesanyer

+0

'std :: unique_ptr (new T(args ...))'の代わりに 'std :: make_unique (args ...)'を使うのは良い習慣であることに注意してください。安全性。 –

関連する問題