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;
}
ここでは、割り当てるfoo
とnew
、それがヒープに割り当てられているので、あなたが呼び出すまで残る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_unique
C ++ 14以降。また、する必要があります#include <memory>
それらを使用できるようにします。このチェックアウトのリンクをヒープとスタック、との違いについての詳細を学ぶためにこの1についての詳細を学ぶためにstd::unique_ptr
、移動-セマンティクス。