classes, pointers, vectors, and memory allocation

Discussion in 'C++' started by mosfets@gmail.com, Feb 6, 2005.

  1. Guest

    Hi,

    I'm having a little trouble figuring out the difference in terms of
    memory allocation between:

    class person_info;

    class A {

    private:
    vector<person_info> list;
    };


    class B {

    private:
    vector<person_info*> list;
    };

    int func1() {

    A* ptr1 = new A();
    B* ptr2 = new B();

    person_info info_stack;
    person_info* info_heap = new person_info();
    }

    ptr1 and ptr2 will be dynamically allocated in the heap, but when I add
    info_stack to ptr1's vector list, info_stack will be copied into the
    heap??? Or will info_stack still reside in the stack? If it is added
    into the heap, does A's memory get enlarged as a whole chunk? If there
    is not enough space for the whole chunk, will A get copied into another
    chunk in the heap big enough to fit it?
    What happens when I exit func1 and info_stack gets destroyed, what will
    happen to the info_stack I put into the vector in ptr1? Can I still
    access it and keep using it?

    When i add info_heap to ptr2's vector list, will the memory of B in the
    heap be enlarged as a whole chunk?


    Sorry for so many questions, but I've been really confused about this
    for a while.

    Thanks for any help, and for reading this!
    John G
     
    , Feb 6, 2005
    #1
    1. Advertising

  2. Guest

    wrote:
    > Hi,
    >
    > I'm having a little trouble figuring out the difference in terms of
    > memory allocation between:
    >
    > class person_info;
    >
    > class A {
    > private:
    > vector<person_info> list;
    > };
    >
    > class B {
    > private:
    > vector<person_info*> list;
    > };


    The first class contains a vector of person_info, whereas the second
    contains a vector of pointer-to-person_info.

    > int func1()
    > {
    > A* ptr1 = new A();
    > B* ptr2 = new B();
    >
    > person_info info_stack;
    > person_info* info_heap = new person_info();
    > }
    >
    > ptr1 and ptr2 will be dynamically allocated in the heap, but when I

    add
    > info_stack to ptr1's vector list, info_stack will be copied into the
    > heap???


    Standard containers like vector are value-oriented, meaning they
    store copies of whatever objects you add to them. So yes, info_stack
    will be copied to wherever the vector stores its contents, which is
    probably a chunk of memory allocated on the 'heap' (called the
    'free store' by the C++ standard).

    > Or will info_stack still reside in the stack?


    info_stack still exists on the 'stack' ('free store' in standardese)
    and will continue to do so until it passes out of scope. The vector
    ptr1->list contains a separate person_info object which was created
    by copying info_stack. These are now two separate objects.

    > If it is added
    > into the heap, does A's memory get enlarged as a whole chunk? If

    there
    > is not enough space for the whole chunk, will A get copied into

    another
    > chunk in the heap big enough to fit it?


    The size of A doesn't change over time. In fact, sizeof(A) is a
    constant known at compile time. However, many objects allocate memory
    dynamically (from the free store, aka., heap). For example, a vector
    typically contains a pointer to a memory buffer that contains the
    elements of the vector. The vector allocates the memory, manages it,
    and eventually frees it. All that memory management is part of the
    internal implementation of vector and is hidden from you.

    > What happens when I exit func1 and info_stack gets destroyed, what

    will
    > happen to the info_stack I put into the vector in ptr1? Can I still
    > access it and keep using it?


    Yes, the vector stores a copy, not the object itself.

    > When i add info_heap to ptr2's vector list, will the memory of B in

    the
    > heap be enlarged as a whole chunk?


    Same as above, sizeof(vector) doesn't change, but the total memory
    used by a vector might change over time because the vector can
    allocate memory from the free store.

    As to the difference between the two vectors, the key to understanding
    a vector of pointers (or pointers generally) is that the pointer and
    the thing it points to (the pointee) are two distinct objects. Let me
    explain with another example:

    void f()
    {
    int n = 1;
    int* p = new int(2);

    // There are now two objects on the 'stack' (n and p) and one
    object
    // on the 'heap' (the integer p points to).

    vector<int> v;
    v.push_back(n);
    v.push_back(*p);

    // We now have a third object on the 'stack' (v), which is a
    // vector containing two objects of type int. Vectors and other
    // standard containers are value-oriented, meaning they store
    // *copies* of the objects you add to them. Thus, we now have a
    // total of four integers, n, *p, v[0], and v[1]. Where are the
    // last two integers? Wherever the vector decides to put them.
    // Most likely, it will have allocated some memory on the 'heap',
    // but the point is it's the vector's job to manage that memory
    // (including freeing it when the vector itself is destroyed)
    // so you don't need to care.

    vector<int*> w;
    w.push_back(p);
    w.push_back(&n);

    // The fourth object on the 'stack' (w) is also a vector, and it
    // two contains two objects, in this case of type pointer-to-int.
    // A key to understanding pointers in C++ is that a pointer is an
    // object in its own right, distinct from the thing it points to
    // (the 'pointee'). We've added two pointers to w (p and the
    // address of n) and it has stored copies of them. It 'owns' those
    // copies and is responsible for eventually freeing them -- just
    // like the vector of ints -- but it's important to understand
    // that w's ownership only extends to the pointers themselves, not
    // to the objects they point to.
    //
    // That's why, when you have a vector of pointers, it is up to
    // *you* to manage the lifetime of whatever objects those pointers
    // point to. The vector only 'owns' the pointers themselves; and a
    // raw pointer (unlike some 'smart pointer' classes) doesn't 'own'
    // anything.
    //
    // Since you asked about memory layout, here's a diagram of what
    // our program might look like so far:
    //
    // 'stack' 'heap'
    //
    // +-------+
    // n | 1 | <-----------------------+
    // +-------+ |
    // +-------+ +-------+ |
    // p | * ---------> | 2 | <--+ |
    // +-------+ +-------+ | |
    // +-------+ | |
    // v | ... | +-------+ | |
    // | * ---------> | 1 | | |
    // | ... | +-------+ | |
    // +-------+ | 2 | | |
    // +-------+ +-------+ | |
    // w | ... | +-------+ | |
    // | * ---------> | * -------+ |
    // | ... | +-------+ |
    // +-------+ | * -----------+
    // +-------+
    //
    // From the preceding discussion, it should be clear that we (not
    // the vector w) are responsibe for eventually deleting the object
    // we earlier allocated using new. So here we go:

    delete p;

    // How should one describe the statement above? Many people would
    // say we just 'deleted the pointer p.' That's fine as long as you
    // understand that it's not precisely true. What we've actually
    // deleted is the pointee, the integer p pointed to. The pointer
    // object itself (i.e., p) still exists, although now it holds
    // an invalid pointer value, which means we're not allowed to do
    // anything with it except assign to it.

    p = &n; // p still exists; let's assign to it just to show we can
    p = NULL; // another equally useless assignment
    }
     
    , Feb 6, 2005
    #2
    1. Advertising

  3. Guest

    Thanks for the nice detailed reply! It helped alot in my understanding
    :)

    Regards,
    John G
     
    , Feb 6, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    5
    Views:
    383
    -berlin.de
    Dec 24, 2004
  2. Ken
    Replies:
    24
    Views:
    3,951
    Ben Bacarisse
    Nov 30, 2006
  3. chris
    Replies:
    6
    Views:
    1,033
    chris
    Oct 28, 2005
  4. Replies:
    3
    Views:
    729
    Shadowman
    Mar 26, 2008
  5. Guest
    Replies:
    0
    Views:
    485
    Guest
    Sep 14, 2005
Loading...

Share This Page