Home > Software design >  What happens when I access a pointer when it's stored in a vector which is on the stack?
What happens when I access a pointer when it's stored in a vector which is on the stack?

Time:08-27

std::vector<object*> objects;
Object* o = new Object();

objects.push_back(o);

I want to access objects[0]. So, when I access it, is there a pointer to the stack, then the heap? Or, how does this work?

CodePudding user response:

There's a few things to unpack here.

First off, let's say you have a vector<object*> as you state, and that it is declared with automatic storage duration.

void f()
{
    // declared with automatic storage duration "on the stack"
    std::vector<object*> my_objects;
}

A vector by it's nature stores a contiguous block of memory, which is essentially an array of n objects of which it can store, in our example the vector can contain 0..n object*, and the implementation will do that by having a pointer to the first element, and that contiguous block of memory is stored "on the heap".

void f()
{
    // declared with automatic storage duration "on the stack"
    std::vector<object*> my_objects;

    // now, my_objects holds 10 object*, and the storage for them
    // is allocated "on the heap"
    my_objects.resize(10);
}

It gets interesting because when we're storing object* we can't know if it was allocated on the heap or not. Take the following example:

void f()
{
    // declared with automatic storage duration "on the stack"
    std::vector<object*> my_objects;

    // now, my_objects holds 2 object*, and the storage for them
    // is allocated "on the heap"
    my_objects.resize(2);

    auto dyn_obj = std::make_unique<object>();
    object auto_obj;

    my_objects[0] = dyn_obj.get();
    my_objects[1] = &auto_obj;
}

Above, we have a situation where the storage for my_objects.data() is allocated on the heap, the object pointed to by my_objects[0] is allocated on the heap, while the object pointed to by my_objects[1] is not.

As in your example:

std::vector<object*> my_objects; // automatic storage duration
object* o = new object;          // o has automatic storage duration
                                 // while what it points to is "on the heap"

 my_objects.push_back(o);        // an allocation will happen
                                 // because my_objects has to
                                 // allocate storage to hold o

my_objects is "on the stack", as is o. When the scope containing these things is exited, they will be "destroyed". my_objects will run it's destructor, while o will "just go away".

The call to my_objects.push_back() will allocate memory "on the heap" to hold 1 * sizeof(object*) ( at least ), and will copy the value of o into that storage space.

  • Related