Do class objects declared on the stack have the same lifetime as other stack variables?
I have this code:
#include <stdio.h>
#include <vector>
using std::vector;
#include <string>
using std::string;
class Child;
class Parent
{
public:
Parent(string s) : name(s) { };
vector<Child> children;
string name;
};
class Child
{
public:
Child() { /* I need this for serialization */ };
Child(Parent *p) : parent(p) { };
Parent *parent;
};
Parent
family()
{
Parent p("John Doe");
int i;
printf("family:\n\tparent: 0x%x\n\ti: %x\n", &p, &i);
for (i = 0; i < 2; ++i)
p.children.push_back(Child(&p));
return p;
}
int
main(void)
{
Parent p = family();
printf("main:\n\tparent: 0x%x\n", &p);
for (unsigned int i = 0; i < p.children.size(); ++i)
printf
(
"\t\tchild[%d]: parent: 0x%x parent.name '%s'\n",
i,
p.children[i].parent,
p.children[i].parent->name.c_str()
);
return 0;
}
My questions:
family, is Parent p declared on the stack? From looking at the output, it would seem soChild goes on the stack too, right?Child instance, I pass it a pointer to a stack variable. I imagine this is a big no-no, because stack variables are guaranteed to live only until the end of the function. After that the stack should get popped and the variables will be destroyed. Is this correct?vector.push_back() passes arguments by reference, so at the end of the family function, p.children just contains references to the local variables, right?main, why can I access the parent and each of its children? Is it all because the local variables from family are still intact and haven't been overwritten by some subsequent function call? I think I'm misunderstanding where stuff lives in memory in C++. I'd really like to be pointed a resource that explains it well. Thanks in advance.
EDIT
Output from compiling the source and running:
misha@misha-K42Jr:~/Desktop/stackoverflow$ ./a.out
family:
parent: 0x2aa47470
i: 2aa47438
main:
parent: 0x2aa47470
child[0]: parent: 0x2aa47470 parent.name 'John Doe'
child[1]: parent: 0x2aa47470 parent.name 'John Doe'
It all works because vector makes copies of everything that you push_back. Your family function is also returning a copy, so even though the stack variable p goes out of scope and gets destroyed, the copy is valid.
I should point out that the Parent pointers retained by the Child objects will be invalid after the end of the family function. Since you didn't explicitly create a copy constructor in Child, one was generated for you automatically by the compiler, and it does a straight copy of the pointer; the pointer will point to an invalid object once p goes out of scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With