15

Boost のmake_shared()関数は、shared_ptr.

make_scoped()同等のものがないのはなぜですか?一般的なベストプラクティスはありますか?

これは、私にとって安全ではないと思われるboost::scoped_ptrドキュメントのコード例です。

    boost::scoped_ptr<Shoe> x(new Shoe);

このコード行は、次の 3 つのことを順番に実行します。

  • にヒープメモリを割り当てますShoe
  • のコンストラクターを呼び出しますShoe
  • のコンストラクターを呼び出しますboost::scoped_ptr<Shoe>

コンストラクターがShoe例外をスローすると、 メモリ リークが発生します。 (R. Martinho Fernandes の回答を参照)scoped_ptrまだ構築されていないため、解放は処理されません。

これは見落としですか?または、私が気付かなかった解決策はありますか?

4

3 に答える 3

15

scoped_ptrpredates はセマンティクスを移動し、設計上コピーできません。したがって、make_scoped関数からオブジェクトを返すためには、その型が移動可能またはコピー可能でなければならないため、実装は不可能です。

于 2012-07-05T03:00:28.083 に答える
14

コンストラクターが失敗した場合、メモリ リークは発生しません。これは のセマンティクスの一部であり、newスマート ポインターは含まれません。

struct Foo { Foo() { throw 23; } };
new Foo(); // no memory leaked

によって提供される追加の例外安全性は、関数呼び出しの引数の場合のように、式で 2 つの をmake_shared初期化していて、2 つの初期化が順序付けされていない場合に発生します。shared_ptr

struct Bar {
    Bar(bool fail) {
        if(fail) throw 17;
    }
}
f(shared_ptr<Bar>(new Bar(true)), shared_ptr<Bar>(new Bar(false)));

new Bar(true)shared_ptr<Bar>(new Bar(true))new Bar(false)およびの評価の間に順序付けがないためshared_ptr<Bar>(new Bar(false))、次のことが発生する可能性があります。

  1. new Bar(false)が評価され、成功します。メモリが割り当てられます。
  2. new Bar(true)評価されて失敗します。この評価の結果としてメモリ リークは発生しません。

shared_ptrこの時点ではNoが構築されたため、#1 で割り当てられたメモリがリークしています。

于 2012-07-05T02:57:18.343 に答える
1

Shoe がスローした場合、Shoe は構築されないため、scoped_ptr が実際にできることは何もありません。いいえ?scoped_ptr x はスタック上にあり、スコープの終了時にクリーンアップされます。

于 2012-07-05T02:56:48.847 に答える