std::vector的容量会降低吗?
Will a std::vector's capacity ever be reduced?
>C++14 最终工作草案对std::vector
做出了以下评论:
存储管理是自动处理的,但可以给出提示以提高效率。
CPP偏好 说:
载体的存储是自动处理的,根据需要进行扩展和收缩。
动态数组的维基百科条目说:
C++ 的
std::vector
和 Rust 的std::vec::Vec
是动态数组的实现
所以我认为当一个向量的容量远大于它的大小时,它应该自动减小它的容量。我编写了以下代码来检查我的假设:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {};
cout << "initialization" << endl;
cout << " capacity: " << v.capacity() << endl;
cout << " size: " << v.size() << endl;
for (int i = 1; i <= 10000; i++)
v.push_back(i);
cout << "after inserting a lot of elements" << endl;
cout << " capacity: " << v.capacity() << endl;
cout << " size: " << v.size() << endl;
v.erase(v.begin() + 1, v.begin() + 10000);
cout << "after erasing a lot of elements" << endl;
cout << " capacity: " << v.capacity() << endl;
cout << " size: " << v.size() << endl;
v.push_back(9);
cout << "after inserting another element" << endl;
cout << " capacity: " << v.capacity() << endl;
cout << " size: " << v.size() << endl;
}
我使用g++ -std=c++14 code.cc
来编译代码。运行结果a.out
将生成以下输出。我正在使用macOS Mojave。
initialization
capacity: 0
size: 0
after inserting a lot of elements
capacity: 16384
size: 10000
after erasing a lot of elements
capacity: 16384
size: 1
after inserting another element
capacity: 16384
size: 2
因此,似乎std::vector
即使其容量远大于其大小也不会降低其容量。
std::vector
会减少其容量吗?
那么,是否有一些条件可以触发其产能的减少呢?
所以我认为当一个向量的容量远大于它的大小时,它应该降低它的容量。
首先,标准必须具体说明"容量远大于其大小"的含义。这将限制实施目前对重新分配战略的选择。
其次,如果减少容量需要重新分配和移动所有剩余的元素。这意味着所有迭代器都可能因擦除而失效,从而限制了安全使用。
目前,擦除状态
使迭代器和引用在擦除点或之后失效,包括
end()
迭代器。
第三,一个载体再次达到其高容量水位线的可能性与它长时间保持小水位的可能性一样大。
对于许多有效方案,您将使使用情况变得更糟,因为释放大量分配的可疑好处。现代虚拟内存系统可以很好地处理旧分配,这些分配严格比必要时间更长。
那么,是否有一些条件可以触发其产能的减少呢?
是的,shrink_to_fit
是做你想做的事的明确要求。如果您确实希望它重新分配给较小的大小,您可以要求这样做。其他会受到螫头伤害的用法不受影响。
如果实现中的std::vector::shrink_to_fit()
没有实现您想要实现的目标(因为它只是发出一个非约束性请求来减少向量的容量(,您可以考虑在向量v
上应用交换以适应习惯用法:
std::vector<int> v;
// ...
{
std::vector<int> tmp(v); // create a copy of vector v
tmp.swap(v);
// vector tmp goes out of scope --> tmp is destroyed
}
或者简单地作为单行:
std::vector<int>(v).swap(v);
这个成语包括创建一个临时向量对象,该对象由原始向量v
的元素组成,然后将生成的临时对象与原始向量交换v
。
应用这个成语交换生成的临时向量和v
的能力。 如果生成的临时容量低于原始矢量v
,这将导致v
具有较低的容量。如果v.size()
远低于v.capacity()
,则很可能是这种情况。
取决于在哪些操作下。如果您包括所有这些,那么是的。
参见 [vector.capacity]p9 (shrink_to_fit
(:
备注:
shrink_to_fit
是一项不具约束力的请求,旨在将capacity()
减少到size()
。[注意:该请求不具有约束力,允许为特定于实现的优化留有余地。
和 [vector.capacity]p10 (swap
(:
效果:将
*this
的内容和capacity()
与x
的内容和交换。
换句话说,使用shrink_to_fit()
,您可能会减少容量。使用swap()
,只要您能够以较少的capacity()
创建另一个vector
,如果您swap()
它们,则可以保证减少capacity()
(但请注意,"原始"容量,即现在另一个对象的容量,本身不会减少(。
关于以下方面的快速说明:
所以我认为当一个向量的容量远大于它的大小时,它应该降低它的容量。我编写了以下代码来检查我的假设:
为了减少capacity()
,实现需要(通常(分配内存(并移动/复制元素并释放原始存储(,这是一个非常昂贵的操作,在擦除元素时没有人想要。
最重要的是,如果您的程序随后再次达到其新capacity()
(这很可能,因为您之前已经这样做了(,则必须再次重复该过程。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- std::vector的容量会降低吗?
- 将结构 std::memcpy 转换为具有足够容量的 std::vector 是未定义的行为<char>吗?
- "Safe"将元素添加到 std::vector 的方法,超出了其 size() 但低于其容量 ()
- 如何在vector::clear()上保持向量元素的容量
- std::vector的容量是如何确定的
- 提高 std::vector 的存储容量/性能
- 为什么 Vector 的大小() 和容量 () 在 push_back() 之后不同
- vector::resize增加了多少容量?
- Vector.at()阻塞,尽管索引远远低于容量
- 是否允许 vector::insert 只保留一次,避免进一步的容量检查
- 设置*both*元素和std::vector的初始容量
- std::vector *必须*在增加容量时移动对象吗?或者,分配器可以"reallocate"吗?
- push_back()后,vector的容量发生变化
- pop_back()会减少vector的容量吗?(c++)
- shrink_to_fit是将' std::vector '的容量缩减到它的大小的正确方法吗?
- Vector初始容量
- C++:为另一个容器中的std::vector保留容量
- vector::push_back何时增加容量
- 如何将std::vector的容量限制为元素的数量