C++向量内存使用 - 它是否会被释放?

6
我知道当超出向量的capacity()时,向量的大小会增加一倍。这个操作需要一些时间,这就是为什么向量应该具有平均常数时间来添加元素,使用push_back()
我想知道的是...当一个向量缩小到其size()小于capacity()的一半时会发生什么。
向量是否会释放它们使用的内存,或者只有在向量被销毁时才能释放?
如果它们从不缩小,那么可能会浪费很多内存,但我从未听说过它们具有该功能。

4
我知道向量会加倍,但实际上这是由具体实现决定的。在Microsoft的实现中,向量的增长因子是1.5。 - RedX
如果你要频繁调整大小,你应该考虑使用一种仅使用所需内存的数据结构;例如std::setstd::map,或者你可以自己编写。 - dario_ramos
可能是释放已分配内存的重复问题。 - Jacob
@dario_ramos:同意你说的“自己动手”的观点,但在这之前还有几个可以尝试的选择,而这永远不是一个好主意。 - Martin York
1
@dario_ramos:或者更接近于像std::deque这样的东西。 - Martin York
显示剩余3条评论
5个回答

13

不,它直到被销毁才会释放(即容量从不减少)。 释放一些内存的常见习惯用法是创建一个正确大小的新向量,并使用该向量代替原来的向量:

std::vector<type>(originalVector).swap(originalVector);

(启发自“更多例外情况下的C++”,第7项)


2
被称为 Shrink To Fit - Matthieu M.

3

如果您想确保您的矢量占用尽可能少的空间,您可以这样说:

std::vector<Foo>(my_vector).swap(my_vector);

你也可以调用shrink_to_fit()成员函数,但这只是一个非强制性的请求。

我编辑了问题以使其更清晰... 这里有两个问题。 - user195488
2
当您移动到一个临时变量,然后与该临时变量交换时,占用的存储空间可能不会改变,因为移动可能只是接管指针,而不进行任何重新分配(这是移动语义的主要重点)。虽然shrink_to_fit是一个非绑定请求,但大多数库都会实现它。同样,将一个向量创建为另一个的副本不能保证产生最小容量,尽管通常会这样做。 - PlasmaHH

0

从向量中删除元素甚至清空整个向量并不一定释放与该元素相关联的任何内存。这是因为自创建以来向量的最大大小是向量未来大小的良好估计。

要使用缩小到适合习语

std::vector<int> v;
//v is swapped with its temporary copy, which is capacity optimal
std::vector<int>(v).swap(v);

C++0x中的解决方案

在C++0x中,一些容器声明了函数shrink_to_fit(),例如vector、deque和basic_string。shrink_to_fit()是一个非绑定请求,用于将capacity()减少到size()。


0

它们不会缩小尺寸。

通常情况下,释放内存并不是很有用。

例如,一个向量现在可能会缩小,但稍后又会增长。释放额外的内存(并复制内存中的所有元素)只为稍后重新分配它将是一种浪费。

如果一个向量正在缩小,那么它也有很大的可能性被缩小到空并被销毁。在这种情况下,随着它的缩小而进行解除分配也是一种浪费时间的行为。

重复使用向量对象以避免分配/解除分配内容也可以是一种有用的优化。如果在缩小时引入解除分配,则会破坏该优化。

基本上,大多数情况下,释放额外的内存并不值得。在极少数情况下,您可以专门要求解除分配。


-2

内存会一直存在,直到向量被销毁。


设置容量并没有帮助,因为它只是对最小容量的请求。至少在我上次查看时是这样,也许随着新标准的出现情况已经改变了。 - john

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