pop_back()能减少向量的容量吗?(C+;+;) 根据C++标准,是 STD::vector:POPYBACK()/允许减少向量的容量吗?< /P>
我之所以这样问是因为我想保证以下代码不会抛出内存不足异常:pop_back()能减少向量的容量吗?(C+;+;) 根据C++标准,是 STD::vector:POPYBACK()/允许减少向量的容量吗?< /P>,c++,c++11,vector,capacity,C++,C++11,Vector,Capacity,我之所以这样问是因为我想保证以下代码不会抛出内存不足异常: my_vec.pop_back(); if (...) my_vec.push_back(...); 假设my_vec是一个std::vector 我想有三种可能: 是的,这可以根据C++03和C++11实现 不,C++11禁止这样做(但C++03不禁止) 不,C++03和C++11都禁止这样做 是的,我的问题与此相关,但我的问题具体是关于标准保证的内容 还要注意的是,中被接受的答案主要是关于如何减少向量的容量,而不是关于何时
my_vec.pop_back();
if (...)
my_vec.push_back(...);
假设my_vec
是一个std::vector
我想有三种可能:
back()
和end()
之外,没有任何迭代器或引用无效
因此,它可能不会重新分配。该页面上没有C++11
标记,这意味着03中也是如此。为了完整起见,我将挖掘章节参考资料并对其进行编辑
编辑:甚至更好:来自C++03
:[lib.container.requirements](23.1),第10段:
无erase()
,pop_-back()
或pop_-front()
函数引发异常
N3337中23.2.1/10的措辞相同(~
C++11
)。否。缩小向量容量的唯一方法是交换技巧,如图所示。还有我下面提到的C++11
方式
此外,正如《基本法》所说:
删除向量中的最后一个元素,有效地将容器大小减少一个 换句话说,它改变向量的大小,而不其容量 看看迭代器的有效性: 结束迭代器和任何迭代器、指针和引用
引用已删除的元素无效。
引用其他对象的迭代器、指针和引用
未删除的元素保证保持
指的是他们在通话前所指的相同元素 在
C++11
中,可以使用std::vector::shrink_to_fit()
来更改容量(有关更多信息,请参阅第1个链接)。(tnx Psyduck)。答案下面有有趣的评论,但这个问题与上述方法无关,因此如果感兴趣,请阅读评论
请注意,即使这种方法也不能保证减少容量
,如下所示:
请求容器减小其容量以适应其大小
请求是非绑定的,容器实现可以自由地进行优化>,并使向量的容量大于其大小
这可能会导致重新分配,但对向量大小没有影响,并且无法更改其>元素
太奇怪了,这个函数不能保证减少容量
和返回
,而第二个函数的ref没有提到任何相关的内容
在我看来,由于ref没有提到容量,这意味着不需要,也就是说容量保持不变
一个有趣的例子是:
#include <iostream>
#include <vector>
int main() {
const int N = 1000000;
std::vector<int> v1;
v1.reserve(N);
for (int i = 0; i < N; ++i) {
v1.push_back(i);
}
std::cout << v1.capacity() << " and size = " << v1.size() << std::endl;
for (int i = 0; i < N - 2; ++i) {
v1.pop_back();
}
std::cout << v1.capacity() << " and size = " << v1.size() << std::endl;
return 0;
}
其中,容量
明显未减少
[编辑]
另一个相关的,也可以标记为重复的,有一些很好的答案。以下是一些有趣的例子:
(一)
去看Scott Meyers有效STL第17项。(OP看起来有一些参考)
基本上,您不能直接减少std::vector的存储大小。“技巧”是>创建一个大小合适的新容器,复制数据并与当前容器交换
(二)
不,如果不进行复制,则无法减少向量的容量
(三)
我并不是说GCC在没有副本的情况下不能有一些方法来做你想做的事情,>但是实现起来很困难(我认为),因为向量需要使用分配器对象来分配和释放内存,分配器的接口不包括reallocation()方法。我不认为这是不可能的,但这可能是棘手的
我建议阅读更多链接
[编辑.2]
这也支持:
问:pop_back()
是否可以减少容量
答:否
当你不能依靠适当的方法来降低容量时(根据你在标准中所读到的内容),你就不能指望pop_back()
会做这样的事情。评论并没有真正解决这个问题。显然,如果std::vector禁止使用std::allocator之外的任何东西,并且如果std::allocator禁止使用其他方法进行扩展,那么就不可能使用相同的基址调整大小,这就不可能降低容量,因为迭代器将失效
我能找到的关于再分配的最接近的信息是stackoverflow评论说
“在某些情况下,没有任何东西可以阻止std::vector这样做(例如,它知道它在使用标准分配器)。允许标准库使用底层系统的知识。-KeithB Jun 23'10于21:39(但未提及参考文献)
已经提交了将realloc添加到std::allocator的想法,但都被拒绝:
不过,论文并没有明确指出std::allocator禁止扩展std::allocator,他们只是说它不需要扩展。它们也没有明确声明禁止std::vector使用对底层系统的API调用。。。所以没有真实的信息
1000000 and size = 1000000
1000000 and size = 2