Deallocating std::vector reserve

Started by
16 comments, last by Kest 17 years, 8 months ago
Is there a full-proof way to put std::vector back into it's construction state or to reduce the size of reserved memory? I've seen people mention using swap() with a temporary stack vector to completely deallocate it. Is that the only method available? I've also heard that some implementations cause clear() to deallocate reserve memory, but the use of the word 'some' seems pretty alarming. Thanks for information
Advertisement
Quote:Original post by Kest
Is there a full-proof way to put std::vector back into it's construction state or to reduce the size of reserved memory? I've seen people mention using swap() with a temporary stack vector to completely deallocate it. Is that the only method available?
Yes, and Yes, afaik.
Quote:

I've also heard that some implementations cause clear() to deallocate reserve memory, but the use of the word 'some' seems pretty alarming.
There's no need to be alarmed. It simply means that the standard doesn't enforce one way or the other with regards to the behaviour. Either implementation will suffice. Some simply do extra above and beyond what is required of them, in an attempt to furthur increase performance.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Quote:Original post by iMalc
Quote:Original post by Kest
Is there a full-proof way to put std::vector back into it's construction state or to reduce the size of reserved memory? I've seen people mention using swap() with a temporary stack vector to completely deallocate it. Is that the only method available?
Yes, and Yes, afaik.

I appreciate your time. Are you saying yes to all three questions? I'm guessing yes to the first and last?

If I need to temporarily increase the capacity of a vector by a huge amount, but know that such capacity will be wasted afterwards, is there a way to force a reallocation to reduce the capacity to a reasonable amount?

Thanks
I think that question is covered pretty comprehensively here (near the bottom of the page).
Thanks much for the link.

There is a big problem with the "right way to Shrink-To-Fit" approach that the author left out. A normal vector memory reserve() allocation resize doesn't create copies, call any constructors, or call any destructors. But his method with swap() does all three. Instead of moving memory from one buffer to another, it creates new objects, copies the old objects, then destroys the old objects. It would become very ugly with complex objects that allocate a lot of data themselves. It would even become dangerous for objects that are designed to exist one at a time.

Will a vector memory shrink even be possible without creating copies of the objects? I would hate to have to do an ugly manual memcpy on the elements.

Thank you again
Quote:Original post by Kest
There is a big problem with the "right way to Shrink-To-Fit" approach that the author left out. ... It would become very ugly with complex objects that allocate a lot of data themselves. ...

Since both resize() and reserve() may copy all the elements, this problem is not restricted to swap(). The solution to the problem is a vector of pointers rather than a vector of objects.

Quote:Original post by Kest
... It would even become dangerous for objects that are designed to exist one at a time.

You cannot use these types of objects in an STL container anyway.

Quote:Original post by Kest
Will a vector memory shrink even be possible without creating copies of the objects? I would hate to have to do an ugly manual memcpy on the elements.

No, since there is no generic way of reallocating memory (bigger or smaller) while guaranteeing that the memory space does not move.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Quote:Original post by JohnBolton
Quote:Original post by Kest
There is a big problem with the "right way to Shrink-To-Fit" approach that the author left out. ... It would become very ugly with complex objects that allocate a lot of data themselves. ...

Since both resize() and reserve() may copy all the elements, this problem is not restricted to swap(). The solution to the problem is a vector of pointers rather than a vector of objects.

I'm pretty sure that's incorrect. Or at least it doesn't match what I read from STL documentation. reserve() resizes do not call constructors, destructors, or copy operators. It only copies vector memory, and does not copy the object's dynamically created memory. swap() is not the problem. He's copying the entire list of elements before swap is called.

Quote:
Quote:Original post by Kest
... It would even become dangerous for objects that are designed to exist one at a time.

You cannot use these types of objects in an STL container anyway.

Of course you can. What if I create a vector of maps, where each map loads a certain file for it's coordinates, deleting that file to mark the fact that the coordinate state is now dynamic in memory?

Quote:
Quote:Original post by Kest
Will a vector memory shrink even be possible without creating copies of the objects? I would hate to have to do an ugly manual memcpy on the elements.

No, since there is no generic way of reallocating memory (bigger or smaller) while guaranteeing that the memory space does not move.

Of course it's necessary to copy the generic reserved vector memory. By "creating copies of the objects", I'm referring to copying the vector elements through a function or operator.
Quote:Original post by Kest
I'm pretty sure that's incorrect. Or at least it doesn't match what I read from STL documentation. reserve() resizes do not call constructors, destructors, or copy operators. It only copies vector memory, and does not copy the object's dynamically created memory.

If reserve is used to reserve a memory size greater than the current capacity, then the vector will allocate a new memory block of an appropriate size and then use the copy constructor to construct the elements in the new memory blocks from the current elements.

Quote:
Of course you can. What if I create a vector of maps, where each map loads a certain file for it's coordinates, deleting that file to mark the fact that the coordinate state is now dynamic in memory?

Then you're hosed when the copy constructor of the elements kick in.
Wow, it's true. That really limits the types of objects that would work well with it. Even more, a normal list construction only calls the normal contructor for the first element, then calls copy constructors for the rest. Sort of odd behavior. I can't really understand why they wouldn't call the normal constructor for every element in the way operator new does.

Oh well, thanks for pointing that out for me.
Quote:Original post by Kest
Of course you can.

All objects stored in standard containers are required to be assignable and copy-constructable. The requirement for an object to be assignable are that t=u results in t being equivilent to u. Note that having an assignment operator will almost certainly allow the code to compile, but that's not good enough: see auto_ptr for an example.

Yeah, its a limitation, but without it the containers would be horrendously crippled.

CM

This topic is closed to new replies.

Advertisement