C++ container.clear()是否释放/重新分配内部缓冲区?
如果我有一个容器并在其上调用C++ container.clear()是否释放/重新分配内部缓冲区?,c++,c++11,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 c
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);
unordered_集mySet{1,2,3,4,5};
mySet.reserve(1000);
mySet.clear();
//这是没有意义的/多余的吗
//或者我应该像对待刚建造的容器一样对待它?
mySet.reserve(1000);
对ideone()的快速测试表明,在调用clear之后,内部内存缓冲区将被保留。因此,至少对于
unordered_set
上的新版本g++来说,情况就是这样。我的问题是1)如果有标准的话,标准会说些什么;2)这种行为是否在所有容器中都是一致的。这与内存发生的情况无关。它只定义了以下要求:
对于序列容器,我们对clear()
有以下要求:
[C++11§23.2.3]
表100
销毁a
中的所有元素。使所有引用、指针无效,
以及引用a
元素的迭代器,可能使
通过结束迭代器
post:a.empty()
返回true
这并没有提到任何关于记忆的事情。对于关联容器,我们对clear()
有以下要求:
[C++11§23.2.4]
表102
a.erase(a.begin(),a.end())
这导致了擦除(…)
要求,这些要求是:
擦除由q
指向的元素。返回一个迭代器,该迭代器指向擦除元素之前紧跟在q
之后的元素。如果不存在这样的元素,则返回a.end()
这同样没有提到容器内存缓冲区的容量。然后,我们有一些无序的关联容器,它们具有类似的措辞:
[C++11§23.2.5]
表103
删除容器中的所有元素。Post:a.empty()
返回true
总的来说,该标准没有提到在清除
后内部内存缓冲区发生的任何事情。因此,这是未指定的行为,在不同的实现中可能会有所不同
因为
reserve
并非在所有容器中都可用(这会改变容量),而且两者都不是下一个最好的选择(收缩到适合)似乎没有一种很好的方法来清除容器的内部内存。 < P>在C++标准中没有任何标准容器可以释放任何内存的要求。甚至函数std::vector::shrink_to_fit()
也只请求内存的收缩。这个函数被认为是用来代替像
std::vector<T>().swap( myVector );
std::vector().swap(myVector);
这个习惯用法用于真正释放内存,而std::vector::clear()
并不能保证这一点。(事实上,std::vector::clear()
被指定为保持capacity()
不变。)但是,对于没有函数shorn\u to\u fit()
的其他容器,您仍然可以使用此习惯用法 没有具体说明。看见因此(对于向量),可以使用shrink__fit@Cyber-调整大小的方法不适用于无序集
和其他容器。这个问题更一般,它也提出了一些不同的问题。有趣的阅读-谢谢。@标记它取决于容器——例如,std::map
等树结构没有容量。从树中删除值时,该节点将立即被销毁,因此clear()
将释放所有分配的内部节点。clear
不会更改容量。这就是reserve
的含义。得票最多。libc++和libstdc++跨clear()
保存bucket\u count()
。VS-2015没有。