为什么 Vector 的大小() 和容量 () 在 push_back() 之后不同

Why Vector's size() and capacity() is different after push_back()

本文关键字:push back 之后 Vector 为什么 容量      更新时间:2023-10-16

我刚刚开始学习向量,对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_backO(1)复杂性(通常只有一个没有副本的商店,有时是一个商店和一系列副本)。

由于这种扩展策略,您将在大部分时间size() < capacity()。查找shrink_to_fitreserve,以了解如何以更细粒度的方式控制矢量的容量。

注意:对于几何增长率,任何大于 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()返回分配的存储容量的大小意味着它现在可以容纳多少个值。