2

バックグラウンド

ネットワークプロトコル用のドライバーを作成しており、機能があります。write(std::shared_ptr<package> package)ここで、(0=>ヘッダー、1=>本体) です。便宜上、ヘッダーを自動生成し、 の最初の形式を呼び出す関数 を書きたいと思います。そのためには を使用したいのですが、呼び出しから を初期化する際に問題があります。packagestd::array<buffer_ptr,2>write(buffer_ptr body)writestd::make_sharedstd::arraymake_shared

コード

typedef std::shared_ptr<std::vector<uint8_t>> buffer_ptr;
typedef std::array<buffer_ptr, 2> package_t;
typedef std::shared_ptr<package_t> package_ptr;

void connection::write(package_ptr package) {
    ... //do stuff
}

void connection::write(buffer_ptr body) {
    buffer_ptr header = buildHeader(body);
    write(std::make_shared<package_t>(???)) //here I want to initialize the array with {header,body}
}

私が試したもの???

(これらはコンパイルエラーにつながりました)

{header, body}
{{header, body}}
std::initializer_list<buffer_ptr>{header, body}

質問:

  1. これを機能させるための解決策はありますか、それとも次のようなものを書く必要がありますか?

    package_ptr package=新しいパッケージ{header, body}; 書き込み (パッケージ);

    1.b) に頼らなければならないことで、効率が低下しpackage_ptr(new package)ますか? (メモリ要求を節約するために、ポインタとインスタンスの共有割り当てメモリを1つのチャンクにしたことを覚えています)

  2. Cppreferenceでは次のように読み取ります。

    さらに、f(shared_ptr(new int(42)), g()) は、g が例外をスローすると、メモリ リークを引き起こす可能性があります。make_shared を使用すると、この問題は発生しません。

    メモリがリークするのはなぜですか (が呼び出される前int(42)に構築さgれ、g呼び出される前に呼び出される可能性がありますshared_ptr)? そして、1. の代替コードは、そのような潜在的なリークに悩まされるでしょうか?

4

1 に答える 1

1

初め:

arrayコンストラクターを明示的に宣言しません。特に、初期化子リストを取るコンストラクターはありません。

newクリーンな方法は、コード内の明示的なものを避け、標準関数に任せることだと思います:

package_t p = {header, body};
write(std::make_shared<package_t>(p));

newどちらもなかった場合、コードはさらに良く見えたでしょうstd::shared_ptr:

package_t p = {header, body};
write(p);

次に、Cppreference.comには次のように書かれています。

さらに、f(shared_ptr(new int(42)), g()) は、g が例外をスローすると、メモリ リークを引き起こす可能性があります。make_shared を使用すると、この問題は発生しません。

標準では、関数の引数を評価する順序は指定されておらず、同じ結果が得られる限り、式は任意の順序で評価できます。

f(shared_ptr(new int(42)), g())

new int(42)先行する必要がありますが、先行する必要はありshared_ptr()ません。これにより、スローg()の場合にリークが発生する可能性があります。g

f(make_shared<int>(42), g())

割り当ては内部で行われmake_sharedます。g前に呼び出されてスローされた場合make_shared、メモリは決して割り当てられません。

がスローmake_sharedされる前に呼び出されgた場合、オブジェクトは既に作成されており、RAII によりその破棄が保証されます。gshared_ptr

于 2014-04-01T20:01:33.940 に答える