3

Suppose I have an ivar vector<type> myVector;.

I add items to this vector.

Later, I want to "reset" the vector to nothing and add items to again fresh.

Can anyone confirm that the following are true:

myVector.clear(); //removes objects but does not remove memory occupied by prior full size of the vector, even though the vector is now empty with a size of 0

Note that these two sites completely contradict each other: This one says the past-the-end iterators are not invalidated with a clear while this one instead indicates that all iterators, pointers and references related to this container are invalidated. Either way, since the capacity is not changed, then this does not really "reset" the vector.

void someFunction(){
   vector<type> emptyVector;
   myVector.swap(emptyVector);
} // function terminates, thus the prior contents of myVector are deleted when emptyVector goes out of scope

This seems like the best approach and I'd think it achieves the same thing as:

myVector.swap(vector<type>());

Now how is this any better or worse than simply doing this:

myVector=vector<type>();

This will simply set the whole shebang to a new empty vector, so the old spot in memory will automatically be wiped cleaned, right?

johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • 1
    N3485 for sequence containers: *Destroys all elements in a. Invalidates all references, pointers, and iterators referring to the elements of a and may invalidate the past-the-end iterator. post: a.empty() returns true* – chris Mar 29 '13 at 07:04
  • `myVector.swap(vector())` will NOT compile. See my answer. – Nawaz Mar 29 '13 at 07:12
  • 1
    I'm curious: why would you *want* to deallocate the memory allocated by the `vector`? You've destroyed all of the objects. All you're doing is making it so that whatever insertions you call on it will take *longer* by deallocating the memory. – Nicol Bolas Mar 29 '13 at 07:40
  • well suppose you are going to replace all the contents of a vector with new contents but aren't sure the size and want to make sure there is no wasted memory after you've done so due to "old memory" still allocated that isn't being used. I suppose in which case you could `shrink` the vector, perhaps. then there was the issue of past-end iterators perhaps not getting "reset" according to one reference, but I think that is cleared up and that reference was wrong. – johnbakers Mar 29 '13 at 08:21

2 Answers2

2
myVector=vector<type>();

Most implementation of std::vector does the above as copy-and-swap, means internally it does this,

vector<type>().swap(*this); //inside the operator=

which is equivalent to this:

vector<type>().swap(myVector);

So swap() is preferred because this does the necessary things you need in order to empty the vector. No extra work. It is idiomatic, and you will often see this in best C++ code.

The operator=, on the other hand, does other little things beside calling swap(). So calling swap() directly would save you a few CPU cycles.

As you know yourself, clear() is not good enough if you want to make the capacity zero (i.e deallocate the memory).


Note that the following will NOT compile:

myVector.swap(vector<type>()); //compilation error

It is because std::vector::swap accepts the argument by non-const reference, which means the temporary object cannot bind to it.

Hope that helps.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

C++11 introduces vector::shrink_to_fit() which attempts to physically shrink a vector to it's size. However it is not guaranteed to do so. See Here for more info.

so, to physically resize. you could:

myvector.clear();
myvector.shrink_to_fit();
stevedes
  • 46
  • 3