收缩矢量

时间:2009-02-25 16:02:44

标签: c++ stl vector

我的地形引擎出现了问题(使用DirectX)。

我正在使用矢量来保存细节块的顶点。 当块增加细节时,向量就会增加。

但是,当块减少其细节时,矢量的大小不会缩小。

所以,我的问题是:有没有办法缩小向量的大小? 我试过这个:

vertexvector.reserve(16);

4 个答案:

答案 0 :(得分:27)

如果从向量中弹出元素,它不会释放内存(因为这会使迭代器无效进入容器元素)。您可以将矢量复制到新矢量,然后将其与原始矢量交换。这将使它不浪费空间。 Swap具有恒定的时间复杂度,因为交换不能使迭代器无效,而是交换的向量元素:因此它必须只交换内部缓冲区指针。

vector<vertex>(a).swap(a);

它被称为“收缩适合”的习语。顺便提一下,下一个C ++版本包含std :: vector的“shrink_to_fit()”成员函数。

答案 1 :(得分:8)

通常的技巧是用空载体交换:

vector<vertex>(vertexvector.begin(), vertexvector.end()).swap(vertexvector);

答案 2 :(得分:6)

当矢量大小减小时,保留的存储器不会减少,因为它通常对性能更好。缩小向量保留的内存量与增加向量大小超出保留大小一样昂贵,因为它需要:

  1. 向分配器询问新的较小内存位置
  2. 复制旧位置的内容,
  3. 告诉分配器释放旧的内存位置。
  4. 在某些情况下,分配器可以就地调整分配大小,但绝不保证。

    如果您所需的尺寸发生了很大的变化,并且您知道您不希望该矢量再次展开(当地的校长暗示您会,但当然是例外),那么你可以使用litb建议的交换操作来明确缩小你的向量:

    vector<vertex>(a).swap(a);
    

答案 3 :(得分:0)

有一个成员函数,shrink_to_fit。它比大多数其他方法更有效,因为它只会在需要时分配新内存和副本。详情在这里讨论, Is shrink_to_fit the proper way of reducing the capacity a `std::vector` to its size?

如果你不介意libc分配函数realloc甚至更高效,它不会在收缩时复制数据,只需将额外的内存标记为空闲,如果你增长内存并且有内存空闲后它将会标记所使用的所需内存,而不是复制。但是要小心,你正在将C ++ stl模板转移到C void指针中,并且需要了解指针和内存管理是如何工作的,现在很多人都不赞同它作为bug和内存泄漏的来源。