Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating class objects on the stack

Tags:

c++

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:

  • In function family, is Parent p declared on the stack? From looking at the output, it would seem so
  • Each created Child goes on the stack too, right?
  • When I create each 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?
  • Why is it all working? In 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'
like image 360
mpenkov Avatar asked Mar 22 '26 16:03

mpenkov


1 Answers

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.

like image 64
Mark Ransom Avatar answered Mar 25 '26 06:03

Mark Ransom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!