[英]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
返回, foo
就不再存在,并且访问它所在的地址是未定义的行为。 在您的第二次尝试中get_test
发生同样的情况,但这里的问题在于get_test
本身。 你声明Foo* foo;
,但永远不要将它分配给任何东西,这意味着变量foo
指向某个随机地址。 访问它是未定义的行为。 试试这个作为你的get_test
:
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>
才能使用它们。 看看这个链接了解更多关于堆和栈,并且之间的差额这一项,以了解更多有关std::unique_ptr
和移动的语义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.