Sign in to follow this  
EmrldDrgn

Quick std::vector questions

Recommended Posts

Would it be safe to write,
std::vector<object *> array;
array.push_back(new object);
and assume that the object will be deleted when the vector falls out of scope? Conversely (sorta), is it safe to write,
std::vector<object> array;
if(true)
{
   object foo;
   array.push_back(foo)
} //foo falls out of scope
and assume that foo will still be in the vector once it falls out of scope at the end of the if?

Share this post


Link to post
Share on other sites
STL containers use value semantics, that is they obtain copies of the objects you insert into them.

The vector only stores copies of those pointers without knowledge of what they "point at". When the vector is destructed all of its contained objects (in this case pointers) are deallocated, but not the objects they point at. If the vector stores pointers to objects on the heap it is your responsibility that you free whatever they point at before the vector is destroyed.

However boost::ptr_vector does exactly what you want

Share this post


Link to post
Share on other sites
Just to add to fpsgamer's response and answer your second question not relating to pointers in vectors:


std::vector<object> array;
if(true)
{
object foo;
array.push_back(foo)
} //foo falls out of scope


When you do the push_back, as fpsgamer explained, a copy of foo is pushed onto the vector. There are now two instances of your object class, foo and the copy in the vector.

When the closing brace is hit, foo is destroyed and its stack space reclaimed. However, this has no effect on the copy of foo in the vector.

Be aware that even just doing a push_back on a vector can cause the vector to need to reallocate memory. At this point, all the current contents of the vector are copy-constructed into the new memory, then the originals are destructed.

This is worth knowing if your objects have non-trivial construction/destruction. It is also why storing pointers or iterators into a vector is generally a bad idea unless you are absolutely sure the vector is not going to reallocate.

Share this post


Link to post
Share on other sites
Quote:
Original post by EasilyConfused
It is also why storing pointers or iterators into a vector is generally a bad idea unless you are absolutely sure the vector is not going to reallocate.


Why is that? Wouldn't it just copy over the pointers? They'd still point at the same object/area in memory/whatever, right?

Share this post


Link to post
Share on other sites
Quote:
Original post by EmrldDrgn
Quote:
Original post by EasilyConfused
It is also why storing pointers or iterators into a vector is generally a bad idea unless you are absolutely sure the vector is not going to reallocate.


Why is that? Wouldn't it just copy over the pointers? They'd still point at the same object/area in memory/whatever, right?


STL iterators can be invalidated under several conditions. Those conditions are specific to the containers of which the iterator belongs.

For example, if a vectors size exceeds its capacity, the vector will allocate a larger region of memory and copy its contents into that newly allocated buffer. This however will invalidate all existing iterators as they wont be referencing the newly allocated buffer, but old one instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by EmrldDrgn
Quote:
Original post by EasilyConfused
It is also why storing pointers or iterators into a vector is generally a bad idea unless you are absolutely sure the vector is not going to reallocate.


Why is that? Wouldn't it just copy over the pointers? They'd still point at the same object/area in memory/whatever, right?


EasilyConfused isn't talking about storing pointers inside vectors; he's talking about storing pointers (or iterators) to objects stored by value in a vector. For example:
std::vector<int> foo;
foo.push_back(1);
int* bar = &foo[0];
foo.push_back(2);
The second call to push_back may reallocate memory and consequently invalidate the value pointed to by bar.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this