container.clear()是否可以释放/重新分配内部缓冲区?

时间:2015-01-22 19:48:42

标签: c++ c++11

如果我有一个容器并且在其上调用clear(),那么只是会破坏内部的所有元素,还是内部实际释放/分配新内存?这种行为是否超出了C ++标准的范围?

归结为:

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);

对ideone(http://ideone.com/XQi8IT)的快速测试表明,在调用clear之后会保留内部内存缓冲区。所以,至少对于unordered_set上的新版g ++来说就是这种情况。我的问题是1)标准说的是什么,如果有的话,2)这种行为在所有容器中是否一致。

2 个答案:

答案 0 :(得分:13)

没有具体说明内存会发生什么。它只定义了以下要求:

对于序列容器,我们对clear()具有以下要求:

[C++11 §23.2.3]表100

  

销毁a中的所有元素。使所有引用,指针无效,   和迭代器引用a的元素并可能使   过去的迭代器。

     

发布:a.empty()返回true

哪些内容并没有真正提及。对于关联容器,我们对clear()

有此要求

[C++11 §23.2.4]表102

  

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

这导致erase(...)要求:

  

删除q指向的元素。返回一个迭代器,指向在删除元素之前紧跟q之后的元素。如果不存在此类元素,则返回a.end()

这再次没有提及容器的内存缓冲区的容量。然后我们有无序的关联容器,它们的措辞相似:

[C++11 §23.2.5]表103

  

擦除容器中的所有元素。发布:a.empty()返回true

总的来说,标准没有提到clear之后内部存储器缓冲区发生的任何事情。因此,不同的实现可能会有所不同的行为。

由于reserve并非在所有容器中都可用(确实会改变容量)而且两者都不是最好的(shrink_to_fit),因此似乎不是一个好的方法清除容器的内部存储器。

答案 1 :(得分:3)

C ++标准中没有要求任何标准容器释放任何内存。即使函数std::vector<T>::shrink_to_fit()也只请求缩小内存。这个功能被认为可以取代像

这样的习语
std::vector<T>().swap( myVector );

这个习惯用于真正释放内存,std::vector<T>::clear()无法保证。 (事实上​​,std::vector<T>::clear()被指定为保持capacity()不变。)你仍然可以将这个习惯用于其他容器,但没有函数shrink_to_fit()