Search code examples
vectorstlheap-memorystack-memory

push object originally on the stack to a vector, will the objects get lost?


I just started using STL, say I have a rabbit class, now I'm creating a rabbit army...

#include <vector>

vector<rabbit> rabbitArmy (numOfRabbits,rabbit()); 
//Q1: these rabbits are on the heap right?

rabbit* rabbitOnHeap = new rabbit(); 
//Q2: rabbitOnHeap is on the heap right?

rabbit rabbitOnStack; 
//Q3: this rabbit is on the stack right?

rabbitArmy.push_back(rabbitOnStack); 
//Q4: rabbitOnStack will remain stored on the stack? 
//And it will be deleted automatically, though it's put in the rabbitArmy now?

Q4 is the one I'm most concerned with, should I always use new keyword to add rabbit to my army?

Q5: Is there better way to add rabbits to the army than:

rabbitArmy.push_back(*rabbitOnHeap);

Solution

    1. Since you haven't specified otherwise, the objects you put in the vector will be allocated with std::allocator<rabbit>, which uses new. For what it's worth, that's usually called the "free store" rather than the heap1.
    2. Again, the usual term is the free store.
    3. Officially, that's "automatic storage", but yes, on your typical implementation that'll be the stack, and on an implementation that doesn't support a stack in hardware, it'll still be a stack-like (LIFO) data structure of some sort.
    4. When you add an item to a vector (or other standard container) what's actually added to the container is a copy of the item you pass as a parameter. The item you pass as a parameter remains yours to do with as you please. In the case of something with automatic storage class, it'll be destroyed when it goes out of scope -- but the copy of it in the collection will remain valid until it's erased or the collection destroyed, etc.
    5. No. In fact, you should only rarely use new to allocate items you're going to put in a standard collection. Since the item in the array will be a copy of what you pass, you don't normally need to use new to allocate it.
    6. Usually you just push back a local object.

    For example:

    for (i=0; i<10; i++)
        rabbitArmy.push_back(rabbit());
    

    This creates 10 temporary rabbit objects (the rabbit() part), adds a copy of each to the rabbitArmy. Then each of the temporaries is destroyed, but the copies of them in the rabbitArmy remain.


    1. In typical usage, "the heap" refers to memory managed by calloc, malloc, realloc, and free. What new and delete manage is the free store. A new expression, in turn, obtains memory from an operator new (either global or inside a class). operator new and operator delete are specified so they could be almost a direct pass-through to malloc and free respectively, but even when that's the case the heap and free store are normally thought of separately.