【问题标题】:How is the capacity of std::vector determinedstd::vector 的容量是如何确定的
【发布时间】:2012-09-01 16:04:20
【问题描述】:

我知道在 std::vector 中,每次空间用完时大小都会增长。然而,我没有注意到它的增长模式。有人可以向我解释一下这种模式以及为什么选择它。

#include <iostream>
using namespace std;

#include <iostream>
#include <vector>
int main()
{
    vector<int> myVector;
    for(int i =0 ; i < 100; ++i)
    {
        myVector.push_back(i);
        cout << myVector.capacity();
    cout << ", ";
    }
}

结果:

1, 2, 3, 4, 6, 6, 9, 9, 9, 13, 13, 13, 13, 19, 19, 19, 19, 19, 19, 28, 28, 28, 2
8, 28, 28, 28, 28, 28, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 6
3, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 6
3, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 9
4, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 141, 141, 141, 141, 141, 141

【问题讨论】:

  • 它高度依赖编译器,但我在某处读到(虽然忘记了源代码)它在某些实现中增长了 2 倍
  • 这不是标准化的,所以取决于实现。你不能依赖任何模式。
  • 您通常可以依靠这样一个事实,即当容量增加时,它将是new_capacity = old_capacity * some_factor;。变化的主要区域是some_factor 的值。这通常使用整数算术执行,因此对于较小的数字,舍入往往会隐藏底层模式。
  • 如果您使用的是 Microsoft 的标准库,那么它会增加 1.5 倍。 Stephan T. Lavavej 曾在他的一个关于性病的在线视频中这样说。

标签: c++ stdvector


【解决方案1】:

这取决于实现,所以在切换操作系统、编译器等时不要期望相同的模式。

最常见的增长模式是1.5 * previous_capacity2 * previous_capacity。在你的例子中,似乎是前者。

请参阅https://stackoverflow.com/a/1100426/784668,了解为何选择该因素的可能解释。关键是它显然允许重用以前用于存储数组的空闲内存块。

【讨论】:

  • 为什么选择这种模式?为什么不以斐波那契数列为例呢?
  • 斐波那契数列也会以 N push_backs 的 O(log N) 分配结束,但不必要地复杂。奥卡姆剃刀。
  • 我记得读过在没有其他内存分配的情况下斐波那契数列实际上是最好的。与释放内存的最有效重用有关。
【解决方案2】:

这是一个实现细节,你不应该关心它。在您的情况下,它似乎类似于

i += i/2

但稍微复杂一些。

【讨论】:

  • 一般来说似乎没有+1。必须是 1 -> 2 的特例。
  • 我相信它是i += i/2,因为3 进展为4
猜你喜欢
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多