为什么在push_back()后,Vector的size()和capacity()会有所不同

时间:2016-01-15 12:27:50

标签: c++ vector allocation

我刚刚开始学习向量,对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 )

所以array.capacity();是15为什么? ( 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;
}

6 个答案:

答案 0 :(得分:14)

标准规定std::vector<T>::push_back()已经摊销O(1)复杂度。这意味着扩展必须是几何的,即每次填充时存储量加倍。

简单示例:顺序push_back 32 intstd::vector<int>。您将存储所有这些,并且如果每次耗尽时将容量加倍,也会复制31份。为什么31?在存储第二个元素之前,复制第一个元素;在存储第3个之前,你复制元素1-2,在存储第5个之前,你复制1-4,等等。所以你复制1 + 2 + 4 + 8 + 16 = 31次,有32个商店。

进行正式分析表明,您获得O(N)元素的N个商店和副本。这意味着按O(1) 分摊push_back复杂度(通常只有没有副本的商店,有时是商店和一系列副本)。

由于此扩展策略,您大多数时间都会size() < capacity()。查找shrink_to_fitreserve以了解如何以更细粒度的方式控制向量的容量。

注意:对于几何增长率,任何大于1的因子都可以,并且有一些研究声称1.5可以提供更好的性能,因为内存浪费较少(因为在某些时候重新分配的内存可以覆盖旧记忆。)

答案 1 :(得分:9)

这是为了提高效率,因此每次添加元素时都不必扩展基础数据结构。即每次都不必致电delete / new

答案 2 :(得分:5)

std::vector::capacity不是它的实际大小(由size()返回),而是实际内部分配大小的大小。

换句话说,它是在需要另一次重新分配之前可以达到的大小。

每次执行push_back时,为了不在每个插入的元素上调用新的重新分配(这是一个沉重的调用),它不会增加1。它保留更多,因为它不知道你之后是否不会做其他push_back,在这种情况下,它不会为4更改分配的内存大小下一个元素。

在这里,4个下一个元素是1之间的折衷方案,它会最大限度地优化内存分配,但很快就会有另一个重新分配的风险,而且数量很大,这样可以让你快速地生成很多push_back但是可以预留一个没有什么记忆。

注意:如果您想自己指定容量(例如,如果您知道矢量最大大小),则可以使用reserve成员函数执行此操作。

答案 3 :(得分:2)

使用

std::vector<int> array(10); // make room for 10 elements and initialize with 0

你实际用零填充了所有十个空格。添加广告附加元素将导致扩展容量,这要归功于效率。 在你的情况下,调用函数保留是没用的,因为你已经实例化了相同数量的元素。

检查thisthis链接

答案 4 :(得分:1)

Size()返回向量中的值。

并且capacity()返回分配的存储容量大小意味着它现在可以容纳多少个值。

答案 5 :(得分:1)

我认为以下问题可以为您提供有关矢量容量的更多详细信息。

About Vectors growth

我将参考上述问题的答案。

capacity的增长策略需要满足push_back操作的摊销常数时间要求。然后,该策略旨在通常在空间不足时呈指数增长。简而言之,size向量表示现在的元素数量,而captacity表示其在将来用于push_back的能力。