【问题标题】:Does clear() in std::vector generates a memory leak?std::vector 中的 clear() 是否会产生内存泄漏?
【发布时间】:2017-01-11 15:48:37
【问题描述】:

我的问题几乎是这个问题的延伸:Is std::vector memory freed upon a clear?

这里人们解释说,为 std::vector 的元素分配的内存在调用 clear() 后不会被释放。但是该内存是否可供操作系统使用以允许其他程序使用它,或者它是否可供我的程序在其他任何地方使用它?

如果不是(如果继续只为这个向量分配内存并且我不能再访问它)是不是像我们的指针那样的内存泄漏?那么像这样单独使用 clear() 是完全不安全的吧?

如果有人能在这篇文章中澄清我,我会很高兴。谢谢。

【问题讨论】:

    标签: c++ c++11 memory-leaks stdvector


    【解决方案1】:

    std::vector 中的 clear() 是否会产生内存泄漏?

    没有。

    但是,这个内存是否可供操作系统使用以允许其他程序使用它,或者它是否可供我的程序在其他任何地方使用它?

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

    如果内存继续只分配给这个向量,我不能再访问它

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

    不就是像我们用指针那样的内存泄漏吗?

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

    那么像这样单独使用 clear() 是完全不安全的吧?

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

    【讨论】:

    • 我会说内存保证不会在调用clear时被释放,因为它是isn't allowed to change the capacity of the vector
    • "如果继续为向量分配内存,则可以通过向向量中添加新对象来重用内存。"好的,现在知道了。当然,我没有假设内存会被同一向量的其他值重用。谢谢。现在想想好像是个傻问题……哈哈哈我是删掉还是留给别人看?
    • @MagnoSilva 如果它让您感到困惑,那么它肯定也会让其他人感到困惑。最好把它留在这里,这样其他人就不需要重复这个问题了。
    【解决方案2】:

    这里人们解释说,为 std::vector 的元素分配的内存在调用 clear() 后不会被释放。但是该内存是否可供操作系统使用以允许其他程序使用它,或者它是否可供我的程序在其他任何地方使用它?

    不,内存仍将由std::vector 实例持有,并且在向量本身被销毁或调用shrink_to_fit 之前将无法供程序的其余部分使用1支持>.

    如果不是(如果继续只为这个向量分配内存并且我不能再访问它)是不是像我们的指针那样的内存泄漏?

    不是真的。当vector被销毁时,内存仍然被释放。

    那么像这样单独使用 clear() 是完全不安全的吧?

    正如 @user2079303 雄辩地说的那样; clear 本身并不是不安全的,但它会释放内存的假设可能是。

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

    【讨论】:

    • shrink_to_fit 也不能保证释放任何内存。
    • 即使delete 也不能保证实际释放任何内存。
    • @PaulMcKenzie malloc 的实现就像一个永远不会收缩的堆栈,没有操作 free 确实会非常快。
    • 虽然技术上正确,但更好的表述可能是 "shrink_to_fit 不保证释放所有内存"。例如,vector<char>(1) 可能无法缩小到 1 个字节,因此如果需要,可以保留 8 或 16 个字节。
    【解决方案3】:

    这不是泄漏。一般来说,泄漏是指您的程序分配了资源,而您失去了它们的所有句柄。更严格的泄漏定义是这种资源分配随着时间的推移重复发生。

    clear 的简单调用不满足该定义,因为在函数调用之后您仍然可以访问std::vector 对象;对象不会简单地消失。您仍然可以在其上调用 shrink_to_fit,或使用空向量调用 swap。即使这样也没有必要,因为最终std::vector 将被破坏,destructor 会释放占用的内存,或者更准确地说,它会释放存储空间,因为操作系统上会发生什么甚至硬件层面都不在C++语言规则的范围内。

    如果析构函数没有运行,因为 std::vector 永远不会因为您的一些错误的动态内存处理而被破坏,那么 std::vector 对象本身的存在已经导致潜在的泄漏.那么问题不在于std::vector 处理的存储。


    注意clear 仍然会导致std::vector元素 立即被销毁。这具有运行它们的析构函数的重要影响。因此,例如,当您有一个 std::vector<std::string> 并在其上调用 clear 时,所有单独的 std::string 析构函数都会运行,当然 会导致存储立即被释放,前提是实际上有一些由字符串处理的动态内容(即未使用小字符串优化)。但不是std::vector处理的存储,而是std::strings'处理的存储。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-19
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      • 2022-11-04
      • 1970-01-01
      相关资源
      最近更新 更多