C++ 为什么向量';s size()和capacity()在push_back()之后不同

C++ 为什么向量';s size()和capacity()在push_back()之后不同,c++,vector,allocation,C++,Vector,Allocation,我刚开始学习向量,对size()和capacity() 我对他们俩都知之甚少。但为什么这两个节目都不一样呢?甚至数组(10)也为10个元素腾出空间,并用0初始化 在添加数组之前。向后推(5) 所以array.size()是10,这是可以的 所以array.capacity()是10,这是可以的 添加数组后。向后推(5) 所以array.size()是11,这是正常的(已经添加了10次0,然后向后推添加一个元素5) 所以array.capacity()15为什么(是否为一个int保留5个块? #包

我刚开始学习向量,对
size()
capacity()
我对他们俩都知之甚少。但为什么这两个节目都不一样呢?甚至
数组(10)
也为10个元素腾出空间,并用0初始化

在添加
数组之前。向后推(5)

所以
array.size()是10,这是可以的

所以
array.capacity()是10,这是可以的

添加
数组后。向后推(5)

所以
array.size()是11,这是正常的
(已经添加了10次0,然后向后推添加一个元素5)

所以
array.capacity()15为什么<代码>(是否为一个int保留5个块?

#包括
#包括
int main(){
std::vector数组(10);//为10个元素腾出空间并用0初始化
array.reserve(10);//为10个元素腾出空间
阵列。推回(5);

std::cout这是为了提高效率,这样它就不必在每次添加元素时都扩展基础数据结构。也就是说,不必每次都调用
delete
/
new

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

换言之,这是它在需要再次重新分配之前能够达到的规模

它不会在每次执行
推回操作时增加1,以避免调用新的重新分配(这是一个沉重的调用)在每个插入的元素上。它会保留更多,因为它不知道您是否会在插入后立即执行其他
推回操作,在这种情况下,它不必为接下来的4个元素更改分配的内存大小

在这里,接下来的4个元素是1和大量元素之间的折衷,1将最大限度地优化内存分配,但很快会出现另一次重新分配的风险,而大量元素将允许您快速执行许多
推回操作,但可能会免费保留大量内存

注意:如果您想自己指定容量(例如,如果您知道向量的最大大小),可以使用成员函数进行指定。

size()
返回向量中的值数量


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

标准要求
std::vector::push_back()
已摊销
O(1)
complexity。这意味着扩展必须以几何形式进行,即每次填充时将存储量增加一倍

简单示例:按顺序
push_back
32
int
s到
std::vector
中。您将存储所有元素一次,如果每次容量增加一倍,还将进行31次复制。为什么是31次?在存储第二个元素之前,您复制了第一个;在存储第三个元素之前,您复制了元素1-2,在存储第五个元素之前,您复制了元素1-2py 1-4,等等。所以你复制了1+2+4+8+16=31次,有32个存储

进行形式化分析表明,您可以获得
O(N)
元素的
N
存储和副本。这意味着每个
push\u back
的摊销
O(1)
复杂性(通常只有一个没有副本的存储,有时是一个存储和一系列副本)

由于这种扩展策略,您将在大多数情况下拥有
size()
。查找
shorn\u to_fit
reserve
以了解如何以更细粒度的方式控制向量的容量

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

使用

std::vector<int> array(10); // make room for 10 elements and initialize with 0
std::vector数组(10);//为10个元素腾出空间并用0初始化
实际上,您用零填充了所有的十个空格。由于效率的原因,添加额外的ad元素将导致容量扩大。 在您的情况下,调用函数reserve是无用的,因为您实例化了相同数量的元素


检查并链接

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

我会参考上述问题的答案


容量
的增长策略需要满足
推回
操作的摊销固定时间要求。然后,该策略被设计为在缺少空间时通常具有指数增长。简言之,向量的
大小
表示当前的元素数量,而
容量
显示其用于在将来向后推的能力。

我猜也是为了避免在展开时多次复制所有元素。因此我们无法确定任何向量的确切容量()。@未知是的,我们可以:
容量()
返回在新的重新分配之前可以包含的元素数。为什么在调用push_back()以容纳该向量中即将到来的元素后容量发生了变化?因此我们无法确定确切的容量()?@UnKnown
capacity()是确切的容量。它会在必要时增长,但会以更大的“步长”增长比大小大。您无法判断未来的容量,但您始终可以判断当前的容量。因为数据结构在运行时分配内存。我已经使用了reserve();但我不明白为什么容量会跳到15,即使我只添加了一个整数?@UnKnown:您没有为11个元素保留空间。@UnKnown,因为它分配了多个元素,以便不为接下来的几个元素重新分配,并限制realloc数。它的大小越大,它的大小就越大,以抑制
re提供
实习生电话。因此,在这种情况下,我们无法确定确切的容量()
std::vector<int> array(10); // make room for 10 elements and initialize with 0