3

私は奇妙なセグメンテーション違反に遭遇しました。原因は実際に私をバグに導きました、しかし私はまだセグメンテーション違反がここで引き起こされる理由を理解していません...コードは次のとおりです:

#include <memory>
int main(int argc, char **arv)
{
    int *i = new int;
    std::unique_ptr<int> u1(i);
    std::unique_ptr<int> u2;
    u1 = std::move(u2); // line 7
    std::shared_ptr<int> s1(i); // line 8
    std::shared_ptr<int> s2;
    s2 = s1;
}

g ++ 4.6でコンパイルすると-std=c++0x、セグメンテーション違反が発生します。

7行目をu2 = std::move(u1);(それがバグでした)に変更すると、消えます。8行目をstd::shared_ptr<int> s1(new int(3));(もちろん必要ない)に変更すると、それも消えます。8行目から削除しても、セグメンテーション違反はありません。

したがって、害はありませんが、セグメンテーション違反が発生する理由がわかりません。私が理解している限り、
7行目では空のポインタがu1に割り当てられています。reset()も、スコープの終わりもありません。それにもかかわらず、それi以降は無効のようです。それは意図されていますか?つまり、別のオブジェクトが破壊される可能性があるため、ポインタを移動するときは非常に注意する必要があります。

どう思いますか?どうすればこれから身を守ることができますか?

ありがとう、Steffen

4

2 に答える 2

11

8行目が間違っています。でキャプチャiした後は、他の所有権を取得するオブジェクトunique_ptrに再度渡してはなりません。すべての所有者は削除しようとしますが、これは間違っています。*i

代わりに、一意のポインターから共有ポインターを作成する必要があります。

std::shared_ptr<int> s1(std::move(u2));

(また、あなたは間違った方法を持っています。u1u2

于 2012-05-10T11:13:23.563 に答える
4

この行:

u1 = std::move(u2);

によって保存された前のポインタu1を削除します。したがって、iポインタは解放されます。shared_ptr解放されたポインタを保持することは、未定義の動作です。

于 2012-05-10T11:13:21.740 に答える