繁体   English   中英

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

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

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