简体   繁体   中英

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 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)

From my limited understanding, I believe it is because in get_test() foo is a temporary variable, so the reference doesn't mean anything. 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. The same happens in your second try, but here the problem is in get_test itself. You declare Foo* foo; , but never assign it to anything, which means that the variable foo is pointing to some random address. Accessing it is undefined behavior. Try this as your 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;
}

Here, we allocate foo with new , so it is allocated on the heap, and will remain until you call delete on it. This means you need to make sure to delete it once you are done with it or you will have a memory-leak. In c++14, you could also do it using 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 is available since c++11, std::make_unique since c++14. You will also need to #include <memory> to be able to use them. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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