简体   繁体   中英

Is assigning empty std::vector same as swaping for an empty std::vector?

C++ delete vector, objects, free memory states that in order to release allocated heap memory after clearing an std::vector, one can do:

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

That makes sense, but I wonder whether the following wouldn't achieve the same. Can someone tell me whether there's a difference?

myVector = vector<int>();

In accord with the standard, assignment from a rvalue (ie: move assignment) for (non- std::array ) containers is not allowed to invoke the move constructor or assignment operators of T unless the allocator for that container does not propagate on container move-assignment . This means that the only valid implementation for vector s of such allocators is to destroy the current allocation and adopt the allocation in the rvalue. std::allocator does propagate on container move-assignment, so any move assignment for such containers will force adoption of the rvalue's content.

Does this mean that myVector = vector<int>(); is guaranteed to adopt the empty allocation? Not necessarily. It is entirely valid for an implementation to detect that the rvalue container is empty, destroy its own elements, but preserve its internal allocation for later.

By contrast, it is not viable for an implementation of vector::swap to do the same thing. The iterator/pointer/reference preservation requirements ensure that iterators/pointers/references to objects in one container are mapped to those in the other (so long as the allocators permit this through propagation on container swap). This means that the allocations within the two objects must actually be swapped, even if one of them has no allocation. Assignment has no such iterator preservation requirements.

That being said, assuming that an implementation will be pathological and actively try to avoid your attempts to remove a container's allocation is not really a good idea. Similarly, a call to shrink_to_fit cannot guarantee that the capacity will change... but an implementation that didn't would be a really stupid one.

So one might argue that the best code would be the one that cleanly explains what's happening. swap is an idiom that you have to get someone to explain why you're using it on a prvalue like that. clear() followed by shrink_to_fit makes it clear what you're doing just from the documentation; no explanation is needed.

So maybe consider doing just that.

There's no significant difference between those alternatives.

However, there is a third option which I recommend due to it being more obvious to the reader:

myVector.clear();
myVector.shrink_to_fit();

Can someone tell me whether there's a difference?

In case of myVector = vector<int>();

The old memory isn't necessarily deallocated(released).

But in case of vector<int>().swap(myVector);

old memory deallocation will happen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM