减少stl向量的容量

yni*_*ous 26 c++ stl vector

有没有办法减少矢量的容量?

我的代码将值插入到向量中(事先不知道它们的数字),当这完成时,向量仅用于读取操作.

我想我可以创建一个新的向量,用大小做一个.reseve()并复制项目,但我真的不喜欢额外的复制操作.

PS:我不关心便携式解决方案,只要它适用于gcc.

aJ.*_*aJ. 39

std::vector<T>(v).swap(v);
Run Code Online (Sandbox Code Playgroud)

用另一个向量交换内容交换容量.

  std::vector<T>(v).swap(v); ==> is equivalent to 

 std::vector<T> tmp(v);    // copy elements into a temporary vector
         v.swap(tmp);              // swap internal vector data
Run Code Online (Sandbox Code Playgroud)

Swap()只会改变内部数据结构.

  • @avakar - 是的,这可以保证符合标准(参见aJ对正在发生的事情的分解).但它也保证复制原始矢量的所有元素. (3认同)
  • Michael,您能指出我指定的位置,在调用vector的copy-constructor之后,capacity()== size()?我刚刚扫过,无法找到任何此类保证. (3认同)
  • 对于它的价值,这个答案中概述的方法是Stroustrup在他的"The C++ Programming Language"一书中所说的方式. (3认同)
  • 是的 - 这本质上是一个副本.AFAIK这是执行OP所需要的唯一标准方法.至于避免副本的非标准方式(OP会认为可以接受),我不确定GCC的STL是否具有此功能(但如果确实如此,我不会感到惊讶). (2认同)
  • 是的,我的观点是原始向量的副本可以预分配与原始向量一样多的内存(即,“vector(v).capacity() == v.capacity()”始终保持的实现仍然可以兼容) . 如果没有 `capacity() == size()` 保证(或至少某种 `capacity() &lt; size() + k` 保证),`vector&lt;T&gt;(v).swap(v)` 可能实际上根本不会收缩。 (2认同)

Mic*_*fik 35

使用C++ 11,您可以调用成员函数shrink_to_fit().该草案标准节23.2.6.2说:

shrink_to_fit是一个非约束性请求,以减少capacity()size().[注意:请求是非绑定的,以允许特定于实现的优化的纬度. - 尾注]


Mat*_*ice 14

去看看Scott Meyers Effective STL第17项.

基本上你不能直接减少一个存储大小std::vector.resize()并且reseve()永远不会减少容器的实际内存占用量."技巧"是创建一个合适大小的新容器,复制数据并与当前容器交换.如果我们想清除容器,这很简单:

std::vector<T>().swap(v);
Run Code Online (Sandbox Code Playgroud)

如果我们必须复制数据,那么我们需要复制:

std::vector<T>(v).swap(v);
Run Code Online (Sandbox Code Playgroud)

这样做会创建一个带有旧数据的新向量,执行任何具有所需效果的操作所需的副本.然后调用swap()将只交换对象之间的内部缓冲区.在该行的末尾,删除了创建的临时向量,但它具有来自旧向量的内容,而旧向量具有来自新副本的内容,这是我们需要的确切大小.


ava*_*kar 6

惯用的解决方案是与新构造的矢量交换.

vector<int>().swap(v);
Run Code Online (Sandbox Code Playgroud)

编辑:我误解了这个问题.上面的代码将清除向量.OP希望保持元素不受影响,只是缩小capacity()size().

很难说aJ的代码是否会这样做.我怀疑是否有便携式解决方案.因为gcc,你必须看看它们的特定实现vector.

编辑:所以我偷看了libstdc ++实现.似乎aJ的解决方案确实有效.

vector<int>(v).swap(v);
Run Code Online (Sandbox Code Playgroud)

参见 232行的来源.

  • 注意 - 这会释放向量的内存 - 但它也会删除所有*元素(因为您正在使用空的临时向量进行交换). (2认同)