如果我有一个容器并且在其上调用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)这种行为在所有容器中是否一致。
答案 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()
。