7

我的地形引擎有问题(使用 DirectX)。

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

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

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

vertexvector.reserve(16);
4

4 回答 4

27

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

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

它被称为“Shrink-to-fit”成语。顺便说一句,下一个 C++ 版本包括一个用于 std::vector 的“shrink_to_fit()”成员函数。

于 2009-02-25T16:12:52.143 回答
8

通常的技巧是用一个空向量交换:

vector<vertex>(vertexvector.begin(), vertexvector.end()).swap(vertexvector);
于 2009-02-25T16:11:30.570 回答
6

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

  1. 向分配器请求一个新的、更小的内存位置,
  2. 从旧位置复制内容,然后
  3. 告诉分配器释放旧的内存位置。

在某些情况下,分配器可以就地调整分配的大小,但这绝不是保证。

如果您对所需的大小进行了非常大的更改,并且您知道您不希望该向量再次扩展(局部性原则建议您这样做,但当然也有例外),那么您可以使用 litb 的建议交换操作以显式缩小向量:

vector<vertex>(a).swap(a);
于 2009-02-25T16:16:40.667 回答
1

有一个成员函数,shrink_to_fit。它比大多数其他方法更有效,因为它只会在需要时分配新内存和复制。此处讨论了详细信息, shrink_to_fit 是否是将 `std::vector` 的容量减小到其大小的正确方法?

如果你不介意 libc 分配函数 realloc 效率更高,它不会在收缩时复制数据,只需将多余的内存标记为空闲,如果你增加内存并且在它标记需要后有空闲内存使用的内存,也不复制。不过要小心,您正在从 C++ stl 模板迁移到 C void 指针,并且需要了解指针和内存管理的工作原理,现在许多人不赞成它作为错误和内存泄漏的来源。

于 2014-10-23T20:20:49.103 回答