2017-11-11 6 views
0

私はいくつかのコードを生成するアプリケーションで作業していますが、速度は問題ではありませんが、メモリリークは望ましくありません。shared_ptr、vector、emplace_back、usage pointer outside

ガベージコレクタで他の言語から来たshared_ptrと少し混乱しています。

基本的には、すべてのポインタにshared_ptrを使用するとガベージコレクタと同様の動作をしますが、オブジェクトが参照されなくなったときにそのオブジェクトをremvoveするため、正しく理解しています。

shared_ptrのベクトルでemplace_backを使用するとどうなりますか。

void fun(MyObject* o){ 
    std::vector<std::shared_ptr<MyObject>> v; 
    v.emplace_back(o); 
} 

今私は、ポインタを作成し、関数を呼び出す:

MyObject* o = new MyObject(); 
fun(o); 
//Is o still here? 

Oとどうなりますか、私はこの機能を持っているとしましょうか? emplace_backはどうにかして私の裸のポインタからshared_ptrを作成し、ベクトルが範囲外になるとoを削除しますか?

私は適切な方法が

EDIT ...そんなに悪くなります、私はもパフォーマンスが、コードに気をいけない場合、すべてをshared_ptrのためにあると思います。私は期待どおりに動作するかを理解します。私のアプリケーションのために、私は良い古い新しいと削除し、削除すると思います。アプリケーションは異なるノードを持つツリーであるため、最後にdeleteを呼び出すと、各子ノードを上から下に安全に削除する必要があります。

+1

「shared_ptr everything」は**悪い考えです**。それでもメモリリークが発生する可能性があります。 –

+0

「メモリリークが欲しくない」 'new'を使わないでください。いいえ、本当に。これはオブジェクトの作成を好むべき順序です: '(MyObject o;')を宣言するか、そうでない場合は 'std :: make_unique'を使用する、そうでない場合は' std :: make_shared' 。 – milleniumbug

+0

良いプログラミング実践:生ポインタを渡すと、呼び出し元(関数)は、呼び出し元がオブジェクトの存続期間を担当していることと、呼び出しの存続期間が保証されている必要があります。あなたのコードはこれらのルールを両方破り、そのようなことがある場合、あなたは未定義の動作ゾーンにあなたのアプリケーションを置くことになります。 –

答えて

4

oはどうなりますか?

デストラクタshared_ptrが指しているオブジェクトを削除したため、ダングリングポインタになります。しかし、これはあなたのベクターが破壊されたためです(範囲外になったため)。あなたのベクトルが破壊されなかったならば、oは割り当てられたオブジェクトを指しているでしょう。これはあなたのベクトルの共有ポインタによって管理されます。

私は、

はありません、適切な方法が適切にC++を使用する方法を学ぶことです...適切な方法は、私はそんなに悪く見えますもパフォーマンスが、コードを気にいけない場合、すべてをshared_ptrのためにあると思いますあなたが他の言語から学んだ慣用句に詰まっているだけではありません。あなたが望むならば、あなたはまだ非効率なコードを書くことができます、心配しないでください。

0

oとはどうなりますか? emplace_backはどうにかして私の裸のポインタからshared_ptrを作成し、ベクトルが範囲外になるとoを削除しますか?

これは正しいです。メモリの所有権をvectorが所有するshared_ptrに転送します。ベクトルが破棄されると、オブジェクトoが指すオブジェクトは、shared_ptrのデストラクタによっても破棄されます。一般に、あなたのo-objectは、shared_ptrの参照を保持する他のshared_ptrが存在しない場合、shared_ptrのデストラクタで破棄されます。

私は適切な方法は、目的のためにスマートポインタを使用することです

号...そんなに悪くなります適切な方法は、私がもパフォーマンスが、コードを気にいけない場合、すべてをshared_ptrのためにあると思いますそれはのために設計されています。 shared_ptrはを共有していますリソースの所有権:プログラム内のインスタンス(スレッドなど)に参照が保持されている限り、リソースが有効であることを確認します。あなたのニーズに合ったスマートポインタもあります。特にunique_ptrです。 また、最初に動的メモリ割り当てが必要な場合は、自分自身に尋ねてください。可能であれば、スタックベースの変数を優先する必要があります。

関連する問題