Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does container.clear() free/reallocate internal buffers?

Tags:

c++

c++11

If I have a container and call clear() on it, does that just destruct all of the elements inside or does it actually free/allocate new memory internally too? Is this behavior outside the scope of the C++ standard?

This boils down to:

unordered_set<int> mySet { 1, 2, 3, 4, 5 };
mySet.reserve(1000);
mySet.clear();

//Is this pointless/redundant
//or should I treat my container like it was just constructed?
mySet.reserve(1000);

A quick test on ideone (http://ideone.com/XQi8IT) shows that the internal memory buffer is retained after a call to clear. So, at least for new versions of g++ on unordered_set that is the case. My question goes to 1) what the standard says, if anything and 2) whether this behavior is consistent across all containers.

like image 218
Mark Avatar asked Jan 22 '15 19:01

Mark


People also ask

Does clear free up memory?

clear() don't release or reallocate allocated memory, they just resize vector to zero size, leaving capacity same.

What is the most efficient container to access an element using an index?

Use sequential containers when you need to access elements by position. Use std:vector as your default sequential container, especially as an alternative to built-in arrays. If you add or remove elements frequently at both the front and back of a container, use std::deque.

Which container provides random access to any of the elements of container?

A Random Access Container is a Reversible Container whose iterator type is a Random Access Iterator. It provides amortized constant time access to arbitrary elements.


1 Answers

It's unspecified with what happens to the memory. It just defines the following requirements:

For sequence containers we have the following requirements for clear():

[C++11 §23.2.3] Table 100

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

Which doesn't really mention anything about memory. For associate containers we have this requirement for clear():

[C++11 §23.2.4] Table 102

a.erase(a.begin(),a.end())

Which leads to erase(...) requirements which are:

erases the element pointed to by q. Returns an iterator pointing to the element immediately following q prior to the element being erased. If no such element exists, returns a.end()

Which again, mentions nothing about the capacity of the memory buffer of the container. Then we have unordered associate containers which have similar wording:

[C++11 §23.2.5] Table 103

Erases all elements in the container. Post: a.empty() returns true

Overall, the standard doesn't mention anything happens to the internal memory buffers after clear. So that's unspecified behaviour that could vary amongst different implementations.

Since reserve is not available in all containers (which does change the capacity) and neither is the next best thing (shrink_to_fit) there doesn't seem to be a good way to consistently clear out the internal memory of a container.

like image 71
Rapptz Avatar answered Sep 19 '22 21:09

Rapptz