2013-10-12 12 views
13

共有ポインタを保持するvector.clear()を呼び出した後、shared_ptrが所有するオブジェクトのデストラクタが解放されていないことに気付きました。共有ポインタのベクトル、ベクトルをクリアした後のメモリの問題

コード例を以下に示します。 vector.clear()が呼び出されても、共有ポインタがスコープを超えた後に呼び出されるデストラクタは、リセットすることでベクトル内のすべてのスマートポインタを手動で削除する必要がありますか?アドバイスできる簡単な方法はありますか?

Output : 

constructor 
I am here 
destructor 

Code: 

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

using namespace std; 

class A 
{ 
public: 
    A(){cout << "constructor" << endl;}; 
    ~A(){cout << "destructor" << endl;}; 
}; 

int main() 
{ 
    shared_ptr<A> sharedptr (new A); 
    std::vector<shared_ptr<A> > test; 
    test.push_back(sharedptr); 

    test.clear(); 
    cout << "I am here" << endl; 
} 

答えて

23

あなたは、この場合にはshared_ptr<A>の2つのコピーを持っているが、一つはsharedptr変数とベクトルの要素として他のです。

は今、この代わりに

test.push_back(std::move(sharedptr)); 

ノートでは、元sharedptrは、それが内部に移動し、もはや使用可能ません持っています。もう1つは何もしません。これはshared_ptrを完全に有効に使用しており、sharedptrは範囲外になった後にクリーンアップされます。

+0

あなたの答えは私が探していたものです。どうもありがとう。 –

+0

私は、質問に示されたケースでは、実際には、 'emplace_back'を介してベクター内のベクターを構築する方が好きです。なぜなら、アクセスが可能な名前付き変数(' sharedptr')を避けるためです'std :: move'。 – us2012

4

問題は、push_backがshared_ptrのコピーをベクターに追加し、メインが存在するまで元のままにしたままにしておくと、問題が発生します。 shared_ptrをメインスコープで作成しないと、問題は発生しません。 shared_ptrをメインスコープにするのは避けてください。 push_back呼び出しで一時的なものにします。

Output is now: 

constructor 
I am almost there 
destructor 
I am here 

New code: 

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

using namespace std; 

class A 
{ 
public: 
    A(){cout << "constructor" << endl;}; 
    ~A(){cout << "destructor" << endl;}; 
}; 

int main() 
{ 
    vector<shared_ptr<A> > test; 
    test.push_back(shared_ptr<A>(new A)); 
    cout << "I am almost there" << endl; 
    test.clear(); 
    cout << "I am here" << endl; 
    return 0; 
} 
+0

maked_sharedまたはemplace_backはどうですか? – GameDeveloper

2

ここsharedptrベクターの要素は一度だけ、コンストラクタとデストラクタを呼び出すことになる同じオブジェクトを共有します。

関連する問題