【问题标题】:Why does valgrind say there are no leaks, even though #allocs != #frees?为什么 valgrind 说没有泄漏,即使 #allocs != #frees?
【发布时间】:2020-10-28 14:46:11
【问题描述】:

我正在编写一个 C++ 程序并注意到一些有趣的事情,valgrind 说这个程序没有泄漏,但同时说分配的数量不等于释放的数量。

这对我来说似乎很奇怪:

==8676== HEAP SUMMARY:
==8676==    in use at exit: 0 bytes in 0 blocks
==8676== total heap usage: 42 allocs, 45 frees, 78,672 bytes allocated
==8676==
==8676== All heap blocks were freed -- no leaks are possible

我没有研究这么多,但是如果堆内存没有被释放,它是丢失。由于我们不再有指向它的指针,它永远不会是免费的。那为什么会这样呢?

编辑:所以在这种情况下,我们的 frees 比 allocs 多。 Valgrind 确实以“无效写入”的形式显示错误。但可能我的误解来自于我认为 allocs 和 frees 总是必须彼此相等以避免内存泄漏。

【问题讨论】:

  • 看起来您在此处显示 更多 个空闲而不是 alloc...
  • 请注意,您有 更多 个空闲空间而不是分配空间!如果您使用 NULL 指针调用 free,它什么也不做!但是,没有代码,我真的无法提供任何进一步的解释。
  • @FrançoisAndrieux:输出报告的是 new 和 delete 被调用的次数,而不是它们在代码中出现的次数。
  • @DanielMcLaury delete nullptr; 算作删除调用吗? (当然在代码中我宁愿是delete some_ptr;some_ptr 恰好是nullptr
  • 如果你解决了你的误解(frees vs allocs),这将是一个很好的问题。如果您还添加minimal reproducible example,这将是一个非常好的问题;)

标签: c++ valgrind


【解决方案1】:

如果我没记错的话,这些计数是函数被调用的次数,而不是内存实际被释放的次数。 free() 被指定为接受 NULL,如果接受则为 no-op,因此该计数很可能包括此类情况。

否则,您的程序将(很可能但并非总是)因某种双释放错误而崩溃。

【讨论】:

    【解决方案2】:

    如果您想确切了解 Valgrind 的计数,请使用 --trace-malloc=yes 运行(不要对大型应用程序执行此操作,在这种情况下,每个 allcs 和 deallocs 约 40 个应该没问题)。你可能想在输出中使用c++filt,因为 Valgrind 会打印出乱码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 2013-02-19
      相关资源
      最近更新 更多