如何在构造时为std::vector保留内存?

How do I reserve memory for a std::vector at construction time?

本文关键字:std vector 保留内存      更新时间:2023-10-16

通常我在构建std::vector后立即调用reserve。这通常不会导致std::vector的现有堆分配被销毁并替换为新的堆分配吗?是否有一种方法可以在构造时保留内存,而不是分配堆空间,然后立即销毁它?或者在std::vector中有一个实现技巧来确保这不是一个问题?

可用的构造函数似乎只能用于用值填充std::vector,而不是显式地保留空间。

你的问题是基于一个错误的前提,即默认构造的std::vector<T>将执行[零长度]分配。

它确实没有理由这样做。一个新的向量应该有容量 0 (尽管这是理智所要求的,而不是标准所要求的)。

这样,你的目标本质上已经满足了。

坦率地说,标准库并没有那么愚蠢。

原因可能很讽刺,我们用完了函数签名。

这个要求来自于使用场景,我们确切地知道要保存多少个元素到vector中,但我们真的真的不喜欢n个重复元素的构造函数:

std::vector( size_type count, const T& value = T())

不幸的是签名被上面的构造函数占用了。任何其他可能的签名都可能导致问题。例如

  1. vector(size_type count, size_type reserve_count)将与上述T(size_type)的n重复元素构造函数冲突。

  2. vector(size_type count, const T& value = T(), size_type reserve_count)是一个可能的解决方案,但它太长了,仍然很无聊。我们需要构造一个在调用auto v = vector<T>(0, T(), reserve_count)

  3. 时从不使用的默认值。

其他可行方案:

  1. 提供make_pair/make_unique等函数

  2. 定义了一个从Allocator派生的server,因此可以使用构造函数vector(const Allocator&

auto v = vector<Type>(new Reserver(reserve_count));

如果在编译时已知元素的数目,则可以使用下列元素对vector进行列表初始化:

 class MyClass 
 {
      int x, y, z;
      std::vector<int> v;
  public:
         MyClass(int X, int Y, int Z) : x(X), y(Y), z(Z), v{x, y, z}
         {}
 };

但是这不是很好维护。还有一些更高级的技术,例如可以让std::vector使用的自定义分配器,它可以从预分配的内存池中获取内存,但是我怀疑您是否真的需要这些技术。现代实现可以很容易地优化如此简单的问题。

对象std::vector和它的元素数组不存在于相同的连续内存块中,否则每次调整数组大小时它的地址都会改变,从而无法保持对它的可靠引用。对象的主体只包含控制变量和指向实际数组的指针,并且它将与其他局部变量一起在堆栈中实例化(假设您将它用作局部变量)。此时,该数组将为空,并且可能由指向nullptr的指针表示。所以无论你是在构造时还是在构造后设置reserve,都不会有显著的优化发生。

如果你想要一个静态大小的std::vector被立即保留,你可以使用一个普通的C数组而不是std::vector。只要确保它适合堆栈