std::vector中的clear()会导致内存泄漏吗?

3
我的问题基本上是这个问题的延伸:Is std::vector memory freed upon a clear? 在那里,人们解释说,在调用clear()之后,为std::vector元素分配的内存不会被释放。但是,这个内存会为操作系统释放以允许其他程序使用它,还是仅可供我的程序在其他地方使用?
如果不是(如果内存仅继续为此向量分配且我无法再访问它),那么这不就像我们在使用指针时遇到的内存泄漏吗?那么仅使用clear()就完全不安全了,对吧?
如果有人能澄清这个问题,我会很高兴的。谢谢。
3个回答

7
在这里,人们解释说,在调用clear()后,为std::vector元素分配的内存不会被释放。但是,这个内存会自由给操作系统,以便其他程序可以使用它,还是只能在我的程序中使用?
不,内存仍然由std::vector实例持有,并且在向量本身被销毁或调用shrink_to_fit1之前,将不可供程序的其余部分使用。
如果不是(如果内存仅为此向量分配,并且我无法再访问它),那么它不是像我们在指针中遇到的内存泄漏吗?
不完全是。当向量被销毁时,内存仍然被释放。
那么,像这样单独使用clear()就会非常不安全,对吗?
正如@user2079303所说的那样,“clear并不本质上不安全,但假设它将释放内存可能是不安全的。”

1. 可能。调用shrink_to_fit不能保证释放任何内存。


1
“shrink_to_fit” 也不能保证释放任何内存。 - eerorika
即使是 delete 也不能保证实际上释放了任何内存。 - PaulMcKenzie
@PaulMcKenzie 如果实现一个类似于不会缩小的堆栈的malloc,并且没有操作的free,那确实会非常快。 - eerorika
虽然从技术上讲是正确的,但更好的表述可能是“shrink_to_fit不能保证释放所有内存”。例如,一个 vector<char>(1) 可能无法缩小到 1 字节,因此如果需要,它可以保留 8 或 16 个字节。 - Bo Persson

7

std::vector中的clear()会导致内存泄漏吗?

不会。

但是这个内存是否可供操作系统释放以供其他程序使用,还是只能在我的程序中任意使用?

操作系统可以将内存交换到磁盘上,以允许其他程序使用物理内存。

如果内存仅分配给此向量,并且我无法再访问它

您可以通过将新对象添加到向量中来重用内存。或者通过销毁向量来释放它。析构函数绝对保证释放内存。

这不就像我们在指针中看到的内存泄漏一样吗?

不是的。当指向内存的指针丢失时,才会发生内存泄漏。但在这种情况下,向量安全地跟踪指针,并在其被销毁时释放它。

那么单独使用clear()就会非常不安全,对吧?

clear 本身并非不安全,但假设它将释放内存可能是不安全的。


1
我认为在调用clear时,内存被保证不会被释放,因为它不允许更改向量的容量 - You
如果向量的内存继续被分配,那么您可以通过将新对象添加到向量中来重用内存。好的,现在我明白了。当然,我没有假设内存会被重用于同一向量的其他值。谢谢。现在想想,这似乎是一个愚蠢的问题...哈哈哈。我应该删除它还是留给其他人看呢? - user7303074
2
@MagnoSilva 如果这让你感到困惑,那么肯定也会让其他人感到困惑。最好把它留在这里,这样其他人就不需要重复这个问题了。 - eerorika

1
这并不是一个泄漏。一般来说,泄漏是指程序分配资源后,您失去了对它们的所有句柄。更严格的泄漏定义是当这种资源分配在一段时间内反复发生时。
简单调用“clear”并不能满足该定义,因为函数调用后,您仍然可以访问“std::vector”对象;该对象并不会消失。您仍然可以调用“shrink_to_fit”或将其与空向量“swap”。甚至这也不是必要的,因为最终,“std::vector”将被析构,并释放占用的内存,更确切地说,它释放存储,因为在操作系统甚至硬件级别上发生的情况不在C++语言规则的范围之内。
如果析构函数没有运行,因为由于某些错误的动态内存处理而永远未销毁“std::vector”,那么“std::vector”对象本身已经导致潜在泄漏。问题不在于“std::vector”处理的存储。
请注意,clear 仍会立即销毁 std::vector元素。这具有重要的效果,即运行它们的析构函数。因此,例如,当您拥有一个 std::vector<std::string> 并对其调用 clear 时,那么所有单独的 std::string 析构函数都将运行,当然,会导致存储被立即释放,前提是字符串处理了一些动态内容(即未使用小字符串优化)。但这不是由 std::vector 处理的存储,而是由 std::string 处理的存储。

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