将临时结构指针分配为结构成员
Assign temporary struct pointer as struct member
假设我有以下结构:
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
returns,foo
不再存在,并且访问它所在的地址是未定义的行为。第二次尝试时也会发生同样的情况,但这里的问题出在 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;
}
在这里,我们用new
分配了foo
,所以它分配在堆上,并且会一直保留到你在上面调用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
一旦超出范围(当 test
被销毁时)将负责删除 foo
,并且您不必担心内存泄漏(但是你不能复制 std::unique_ptr
,所以你必须 std::move
它)。
std::unique_ptr
自 c++11 起可用,std::make_unique
自 c++14 起可用。
您还需要 #include <memory>
才能使用它们。
查看此 link to learn more about the difference between heap and stack, and this one 以了解有关 std::unique_ptr
和移动语义的更多信息。
假设我有以下结构:
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
returns,foo
不再存在,并且访问它所在的地址是未定义的行为。第二次尝试时也会发生同样的情况,但这里的问题出在 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;
}
在这里,我们用new
分配了foo
,所以它分配在堆上,并且会一直保留到你在上面调用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
一旦超出范围(当 test
被销毁时)将负责删除 foo
,并且您不必担心内存泄漏(但是你不能复制 std::unique_ptr
,所以你必须 std::move
它)。
std::unique_ptr
自 c++11 起可用,std::make_unique
自 c++14 起可用。
您还需要 #include <memory>
才能使用它们。
查看此 link to learn more about the difference between heap and stack, and this one 以了解有关 std::unique_ptr
和移动语义的更多信息。