構造体のメンバとして割り当てる一時的な構造体のポインタ

イブラヒムファデル:

iは、以下の構造体を持っているとしましょう:

struct Foo
{
  int val;
};
struct Test
{
  Foo *bar;
};

そして私が作りたかったTest構造体を:

Test get_test()
{
  Test test;
  Foo foo;
  foo.val = 10;
  test.bar = &foo;

  cout << "INIT: " << test.bar->val << endl;

  return test;
}

int main()
{
    Test test = get_test();
    cout << "AFTER: " << test.bar->val << endl;
    return 0;
}

出力は以下の通りであります:

INIT: 10
AFTER: 32723

私は違っこれを実行しようとしました。

Test get_test()
{
  Test test;
  Foo *foo;
  foo->val = 10;
  test.bar = foo;

  cout << "INIT: " << test.bar->val << endl;

  return test;
}

しかし、これは私に与えました SIGSEGV (Address boundary error)

私の限られた理解から、私はではので、それがあると信じてget_test() foo、一時的な変数であるので、参照は平均何もしません。どのように私はこれを適切に行うことができますか?

ミルク:

あなたは正しい軌道に乗っています。あなたの最初の例では、いったんget_test戻り、fooもう存在し、それがあったアドレスにアクセスすると、未定義の動作ですされません。同じことが、あなたの2回目の試行で起こるが、ここでの問題はであるget_test自分自身。あなたは宣言しFoo* foo;ますが、変数があることを意味何でも、それを割り当てることはありませんfooいくつかのランダムなアドレスを指しています。それへのアクセスは未定義の動作です。あなたとしてこれを試してみてくださいget_test-function:

Test get_test()
{
  Test test;
  Foo *foo = new Foo();
  foo->val = 10;
  test.bar = foo;

  cout << "INIT: " << test.bar->val << endl;

  return test;
}

ここでは、割り当てるfoonew、それがヒープに割り当てられているので、あなたが呼び出すまで残るdeleteことに。この手段はあなたに確認する必要がありdelete、あなたがそれで行われたり、メモリー・リークを持っています一度。C ++ 14では、あなたも使ってそれを行うことができますstd::unique_ptr

struct Test
{
  std::unique_ptr<Foo> bar;
};
{
  Test test;
  std::unique_ptr<Foo> foo = std::make_unique<Foo>();
  foo->val = 10;
  test.bar = std::move(foo);

  cout << "INIT: " << test.bar->val << endl;

  return test;
}

std::unique_ptr削除の世話をするfoo、それがスコープ外になったら(ときがtest破壊され)、そしてあなたは、メモリリークを心配する必要はありません(ただし、コピーすることはできませんstd::unique_ptrので、あなたがする必要がありますstd::moveが)。std::unique_ptr、C ++ 11以降で使用可能であるstd::make_uniqueC ++ 14以降。また、する必要があります#include <memory>それらを使用できるようにします。このチェックアウトのリンクをヒープとスタック、との違いについての詳細を学ぶためにこの1についての詳細を学ぶためにstd::unique_ptr、移動-セマンティクス。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=383677&siteId=1