为什么使用std::vector::reserve很有用?

3

在C++中,您可以使用push_back方法向向量添加元素。该方法会修改向量的大小。 那么使用std::vector::reserve的目的是什么?我何时应该使用它呢?

使用std::vector::reserve的目的是为向量预留空间,以避免多次重新分配内存。当您知道要向向量添加大量元素时,使用reserve可以提高性能。


2
它的目的是尽量减少或完全消除缓冲区调整大小及其引入的影响(复制/移动可能会变得昂贵,特别是对于大量对象而言)。在operator new/delete的世界中没有realloc等效物。要“扩展”分配需要单独进行分配,需要大量复制或移动,然后释放旧内存。通过“声明”您的数量意图,您可以避免这种微妙之处(一只坏兔子很可爱,但一百万只坏兔子就是一个大问题)。 - WhozCraig
4个回答

6

当你知道至少有n个元素会进入向量时,可以使用reserve。重新调整容器大小是一项昂贵的操作——你需要分配新的内存,将旧内容复制到其中,然后删除旧向量。如果你默认知道将获得至少10000个元素,最好为向量保留大小,而不是让向量重新分配比必要更多次的内存。

简单来说,这都是关于效率的问题。


3
比效率更重要的是:它确保迭代器保持有效。 - James Kanze

4

它可以用来确保迭代器的有效性,或作为优化。当向向量添加元素时,如果新大小大于容量,则必须重新分配向量,将所有现有元素复制(或移动)到新缓冲区中。这会使向量中的所有迭代器无效,并且可能很昂贵。reserve函数确保最小容量。如果您预先知道最大大小并对其进行保留,则添加元素永远不会使新元素前面的迭代器无效,并且永远不需要复制。(对于大多数代码,迭代器有效性的问题强制使用reserve。)


因此,作为最佳实践,人们应该总是调用reserve来避免这些副作用? - Engineer2021
1
需要注意的是,即使有足够充裕的预留缓冲区,一个 "insert(v.begin()...)" 操作也会导致迭代器的有效性出现问题。即使没有调整大小,所有迭代器都会遭受打击。 - WhozCraig
2
并非一定需要这么做。比如,在一个相对较小的循环中使用 push_back,而且能够明确知道没有迭代器时,通常不需要调用 reserve(当你无法设置最终元素数量的合理上限时,也不能有效地使用它)。 - James Kanze
2
@WhozCraig 是的。原始问题提到了 push_back,这可能是最常见的情况。在插入任意点时,通常可以忽略迭代器。 - James Kanze

2

调整向量大小可能会显著降低执行速度(例如在向其添加大量数据时)

参考资料如下:

This effectively increases the container size by one, which causes an automatic
reallocation of the allocated storage space if -and only if- the new vector size
surpasses the current vector capacity.

因此,最好在一个理想的值上调整向量大小,以便您拥有足够的空间存储所有数据且不会浪费。向量的缩小调整时间将加快应用程序的运行速度。


1
为了提高效率,你可以为所需的元素分配内存,如果你知道初始大小,这样向量就可以一次性分配所有内存,而不必在超过分配大小时进行扩展。
[4] Reserve()会手动重新分配空间。使用reserve()的主要原因是效率:如果你知道向量最终需要增长到的容量,则通常更有效地一次性分配该内存,而不依赖于自动重新分配方案。使用reserve()的另一个原因是为了控制迭代器的失效。 来源

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接