[英]Assign temporary struct pointer as struct member
Let's say i have the following structs:假设我有以下结构:
struct Foo
{
int val;
};
struct Test
{
Foo *bar;
};
and I wanted to create a Test
struct:我想创建一个
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;
}
The output is the following:输出如下:
INIT: 10
AFTER: 32723
I tried to do this differently:我试图以不同的方式做到这一点:
Test get_test()
{
Test test;
Foo *foo;
foo->val = 10;
test.bar = foo;
cout << "INIT: " << test.bar->val << endl;
return test;
}
But this gave me a SIGSEGV (Address boundary error)
但这给了我一个
SIGSEGV (Address boundary error)
From my limited understanding, I believe it is because in get_test()
foo
is a temporary variable, so the reference doesn't mean anything.根据我有限的理解,我相信这是因为在
get_test()
foo
是一个临时变量,所以引用没有任何意义。 How can I do this properly?我怎样才能正确地做到这一点?
You are on the right track.你走在正确的轨道上。 In your first example, once
get_test
returns, foo
does not exist anymore, and accessing the address where it was is undefined behavior.在您的第一个示例中,一旦
get_test
返回, foo
就不再存在,并且访问它所在的地址是未定义的行为。 The same happens in your second try, but here the problem is in get_test
itself.在您的第二次尝试中
get_test
发生同样的情况,但这里的问题在于get_test
本身。 You declare Foo* foo;
你声明
Foo* foo;
, but never assign it to anything, which means that the variable foo
is pointing to some random address. ,但永远不要将它分配给任何东西,这意味着变量
foo
指向某个随机地址。 Accessing it is undefined behavior.访问它是未定义的行为。 Try this as your
get_test
-function:试试这个作为你的
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;
}
Here, we allocate foo
with new
, so it is allocated on the heap, and will remain until you call delete
on it.在这里,我们用
new
分配foo
,所以它被分配在堆上,并且会一直保持到你调用delete
为止。 This means you need to make sure to delete
it once you are done with it or you will have a memory-leak.这意味着您需要确保在完成后将其
delete
,否则您将出现内存泄漏。 In c++14, you could also do it using std::unique_ptr
:在 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
will take care of deleting foo
once it goes out of scope (when test
is destroyed), and you don't have to worry about memory-leaks (but you cannot copy a std::unique_ptr
, so you will have to std::move
it). std::unique_ptr
一旦超出范围(当test
被销毁时)将负责删除foo
,并且您不必担心内存泄漏(但您不能复制std::unique_ptr
,因此您将拥有到std::move
它)。 std::unique_ptr
is available since c++11, std::make_unique
since c++14. std::unique_ptr
从 c++11 开始可用, std::make_unique
从 c++14 开始可用。 You will also need to #include <memory>
to be able to use them.您还需要
#include <memory>
才能使用它们。 Check out this link to learn more about the difference between heap and stack, and this one to learn more about std::unique_ptr
and move-semantics.看看这个链接了解更多关于堆和栈,并且之间的差额这一项,以了解更多有关
std::unique_ptr
和移动的语义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.