为什么 Vector 的大小() 和容量 () 在 push_back() 之后不同
Why Vector's size() and capacity() is different after push_back()
我刚刚开始学习向量,对size()
和capacity()
有点困惑我对他们俩知之甚少。但是为什么在这个程序中两者不同?即使array(10)
也为 10 个元素腾出空间并用 0 初始化。
添加array.push_back(5)
之前
所以array.size();
是 10 没关系。
所以array.capacity();
是 10 没关系。
添加array.push_back(5)
后
所以array.size();
是 11 没关系(already 10 time 0 is added and then push_back add one more element 5 )
.
那么 15 array.capacity();
为什么? ( is it reserving 5 blocks for one int? )
.
#include <iostream>
#include <vector>
int main(){
std::vector<int> array(10); // make room for 10 elements and initialize with 0
array.reserve(10); // make room for 10 elements
array.push_back(5);
std::cout << array.size() << std::endl;
std::cout << array.capacity() << std::endl;
return 0;
}
标准要求std::vector<T>::push_back()
已摊销O(1)
复杂性。这意味着扩展必须是几何形状的,例如每次填充时将存储量增加一倍。
简单的例子:按顺序push_back
32 int
s 到一个std::vector<int>
中。您将存储所有这些副本一次,如果每次用完时容量加倍,则还要存储 31 个副本。为什么是31?在存储第二个元素之前,您复制第一个元素;在存储第 3 个之前,您复制元素 1-2,在存储第 5 个之前,您复制 1-4,依此类推。所以你复制 1 + 2 + 4 + 8 + 16 = 31 次,有 32 家商店。
执行形式分析表明,您可以获得N
元素的O(N)
存储和副本。这意味着每push_back
摊 销O(1)
复杂性(通常只有一个没有副本的商店,有时是一个商店和一系列副本)。
由于这种扩展策略,您将在大部分时间size() < capacity()
。查找shrink_to_fit
和reserve
,以了解如何以更细粒度的方式控制矢量的容量。
注意:对于几何增长率,任何大于 1 的因子都可以,并且有一些研究声称 1.5 提供了更好的性能,因为浪费的内存更少(因为在某些时候重新分配的内存可以覆盖旧内存)。
这是为了提高效率,因此它不必在每次添加元素时扩展底层数据结构。 即不必每次都调用delete
/new
。
std::vector::capacity不是它的实际大小(由size()
返回),而是实际内部分配的大小的大小。
换句话说,它是在需要再次重新分配之前可以达到的大小。
每次执行push_back
时,它不会增加 1,以便不对每个插入的元素调用新的重新分配(这是一个繁重的调用)。它保留了更多,因为它不知道你之后是否会做其他push_back
,在这种情况下,它不必为接下来的 4 个元素更改分配的内存大小。
在这里,接下来的 4 个元素是 1 和一个巨大的数字之间的折衷,前者将最大限度地优化内存分配,但很快就会有再次重新分配的风险,后者可以让您快速进行许多push_back
,但可能会白白保留大量内存。
注意:如果您想自己指定容量(例如,如果您知道矢量最大大小),则可以使用保留成员函数来实现。
使用
std::vector<int> array(10); // make room for 10 elements and initialize with 0
你实际上用零填充了所有十个空格。由于效率,添加广告附加元素将导致容量扩展。在您的情况下,调用函数 reserve 是没有用的,因为您已经实例化了相同数量的元素。
检查这个和这个链接
以下问题可以为您提供有关向量容量的更多详细信息。
关于矢量生长
我将参考上述问题中的答案。
capacity
的增长策略需要满足push_back
操作的摊销恒定时间要求。然后,该策略通常设计为在空间不足时呈指数增长。简而言之,向量的size
表示现在的元素数量,而captacity
表示其将来用于push_back
的能力。
Size()
返回向量中的值数。
capacity()
返回分配的存储容量的大小意味着它现在可以容纳多少个值。
- 推导 std::vector::back() 的返回类型
- vector.back() 和 vector[vector.size() - 1] 之间的区别?
- vector.push_back(vector.back()+1) 是未定义的行为吗?
- C++自己的对象堆栈.在 push() 上复制了什么?
- C++ push() 和 pop() 方法使用指针的动态 LinkedList 的问题
- 如何像在javascript中一样"push" c ++映射
- 线路抑制状态错误 C4703 可能未初始化的局部指针变量"back"已使用
- std::vector using back(), pop_back(), push_back(), 得到'double free or corruption'错误
- vector.back()和vector.end()有什么区别
- 列表大小为 1,但 front() 和 back() 不相等
- 返回C++中没有 back() 方法的容器的最后一个元素?
- 在非空 std::list 上使用 std::list.back<int>() 时"Segmentation Fault"
- 模板堆栈类的复制构造函数中的 pop() 和 push() 不起作用
- 我们可以使用Back() - 值索引在其上执行向量插入
- 当我运行以下代码添加str.front() str.back时,它给了我200个,但为什么
- push(ing)back在循环中对象指针
- 在 C++ 中将元素添加到空向量:为什么 push.back 有效而 [] 无效
- 我似乎无法让 v.push.back() 处理字符串
- String::push_back() does not push back
- 向量resize(), push.back(), reserve()方法