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.