如何在C++中清空向量并释放内存

15

我刚接触C++,所以这可能是一个新手问题。但我不太清楚如何从内存中清除它。我在网上搜索并查看了几个答案,但对于如何正确执行我想做的事情还不清楚。

在C++中,如何正确清除向量(vector)的内存?谢谢,如果这是重复的帖子,请原谅。

vector<ElementData> Elements;

正如下面的评论所提到的,我也想返回所使用的内存。

除了容量保持不变之外,它将不会向系统返回任何内存。


你想让向量的容量归零还是让向量本身消失? - NathanOliver
你想要清除向量中存储的元素,还是想要清除向量对象本身从内存中删除? - Xirema
这是一个与安全有关的问题吗? - Christian Hackl
6个回答

25

如果你想将向量重置为空状态,那么我们可以使用 swap 技巧将向量的内容交换到一个临时向量中,然后销毁该向量并释放内存。

vector<ElementData> Elements
// fill the vector up
vector<ElementData>().swap(Elements);

这将创建一个临时空向量,将其与您拥有的向量交换,使其现在为空,然后销毁临时向量中的所有内容。

您可以在此小例子中看到它的工作方式

int main() {
    std::vector<int> foo(500);
    std::cout << foo.capacity() << std::endl;
    std::vector<int>().swap(foo);
    std::cout << foo.capacity() << std::endl;
}       

现场示例


感谢您的帮助。 - JokerMartini
3
为什么不直接使用 Elements = vector<ElementData>(); - Christian Hackl
2
@ChristianHackl 这应该可以工作,但我担心向量仍然能够保持其容量。我不确定标准对此有何规定。 - NathanOliver
1
@Peregring-lk 在 Elements.swap(vector<ElementData>()) 并不起作用,因为 swap 有一个 vector& 参数,所以它无法绑定到临时创建的 vector<ElementData>() - NathanOliver
2
@Peregring-lk 不是的。顺便说一下,制作一个函数,例如template <typename... Params> void clear_vector_memory(std::vector<Params...>& vec) { vector<Params...>().swap(vec); }可能会更好。这样你的代码就变成了 clear_vector_memory(my_vector); - NathanOliver
显示剩余2条评论

17

当您超出作用域或它们所属的类对象被销毁时,std::vector变量通常会自动析构。std::vector的析构函数还会销毁向量中的所有元素。

要显式完全清除向量,请首先清除向量(销毁元素)。

v.clear()

然后返回之前为向量元素保留的内存。

v.shrink_to_fit();

只有在之前的向量可能包含比您要填充的元素更多时,才调用 shrink_to_fit

http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit


FYI,“shrink_to_fit”不需要执行任何操作,因此可能有效,也可能无效。 - NathanOliver
3
是的,但根据“as-if”规则,分配并不可观测,所以标准很难用更强的措辞。我不知道是否有符合C++11标准的编译器具有空操作shrink_to_fit。VS和gcc肯定有“真正”的功能。 - Johan Lundberg

3

当程序结束时,vector的析构函数会被调用并为您删除堆栈上分配的向量。此外,对于向量中的每个ElementData,其析构函数也将被调用。


非常棒的信息,谢谢Chara。 - JokerMartini

1
在大多数情况下,最好的方法是将向量的范围限制在实际需要的范围内。因此,不要像这样做:

而应该这样做:

vector<Elements> Elements;
... do some work with Elements ...
Elements.clear(); // or whatever "trick" you want to use
... do more work where Elements is not needed ...

你会这样做:
{ // begin a new scope
    vector<Elements> Elements;
    ... do some work with Elements ...
} // Elements is now out of scope, its memory has been freed
... do more work where Elements is not needed ...

另一个好处是,当Elements超出作用域后,您不会意外地重复使用它。如果函数很小,您可能不需要创建新的显式作用域。从函数返回将具有相同的效果。

0

你不需要做任何特殊的事情。由于向量和其中的元素都是静态分配的(即未通过new创建),当向量超出范围时,它将被释放,并且所有ElementData内部的析构函数将被调用。如果你有vector<ElementData*>,其中向量仅包含指向ElementData的指针,则还必须自己delete所有ElementData。


-5

Elements.clear() 可以实现你想要的功能。

这里 是向量可用的其余函数。


除了容量保持不变,它不会将任何内存返回给系统。 - NathanOliver
@NathanOliver 我该如何正确释放内存? - JokerMartini
通常情况下你不需要这么做。如果你真的觉得有必要,可以尝试调用 shrink_to_fit 函数。 - Alex

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