简体   繁体   English

将临时结构指针分配为结构成员

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM