【问题标题】:Tracking down a memory leak with Valgrind使用 Valgrind 追踪内存泄漏
【发布时间】:2014-01-20 12:17:40
【问题描述】:

根据 Valgrind 的说法,我的程序中存在相当大的内存泄漏,但我实际上不认为是这种情况。或者也许我只是不知道什么。我是第一次使用 Valgrind,所以我可能解释错了,或者可能把它看得太认真了。

无论如何,Valgrind 告诉我大约 13 MB(56 字节直接,其余的间接)肯定丢失了。有问题的代码如下所示:

Node* newRoot = malloc(sizeof(Node));
newRoot->children[0] = tree->root;
newRoot->children[1] = otherNode;
newRoot->k = 2;

tree->root = newRoot;

您可能会说,我有一个树结构,其中树对象有一个根,一个节点有多个子。在这部分代码中,树被展开到顶部;旧根成为新节点的子节点,然后新节点成为新根。 treeTree*root 成员是 Node 指针,children 是 Node 指针数组。

现在 Valgrind 告诉我上面分配的内存 malloc 丢失了,但据我了解,我指的是新根中的内存块,而旧根则保留为新根的子级。

在我的程序结束时,我递归地释放树中所有节点的内存(通过递归下降到所有子节点,从 root 开始),所以我很确定内存最终会被释放.

我错过了什么吗?有没有办法从 Valgrind 获得更详细的信息,以了解到底发生了什么(未发生)?

【问题讨论】:

  • 也许,向我们展示释放功能会很有用。另外,您使用哪些选项来运行 valgrind?
  • 你能提供valgrind的输出吗?还要确保在 valgrind 输出中区分 definitly lostmaybe lost
  • 谁在你之前指向otherNode,现在那个指针指向哪里?
  • @KirilKirov 哇,真不敢相信我以前没想到这一点。这确实是释放功能。当我愉快地将树降到叶子并正确释放它们时,我完全忘记了释放节点本身。这解决了所有内存泄漏问题——比我预期的要简单得多。谢谢你让我看那里! ^^ 而我对 Valgrind 的所有疑虑顿时烟消云散了。
  • @poke - 很高兴能提供帮助:)。 valgrind 的 memcheck 基本上做的是 - 监控每个内存分配以及分配的内存是否在以后被释放。如果它没有被释放,它会告诉你它是在哪里分配的,因为它不能告诉你它应该在哪里被释放。这就是我要求释放功能的原因。

标签: c memory-leaks valgrind


【解决方案1】:

valgrindmemcheck(默认工具)基本上 用于监控内存泄漏的是 - 监控每个内存分配以及分配的内存是否在以后被释放。如果它没有被释放,它会告诉你它是在哪里分配的,因为它不能告诉你它应该在哪里被释放。

我的意思是——即使分配/添加功能看起来不错,我们/你也应该看看释放功能。根据您问题中的信息,很可能问题就在那里。

另一件可能有用的事情是:你如何运行valgrind?我使用以下选项:

valgrind --trace-children=yes --track-fds=yes --log-fd=2 --error-limit=no \
         --leak-check=full --show-possibly-lost=yes --track-origins=yes \
         --show-reachable=yes executable executable_arguments_if_any

有时verbose 函数也很有用。

【讨论】:

  • 我实际上忘记在我的释放函数中释放内部节点,所以错误实际上是有道理的。修复所有内存泄漏 :) – 我现在只是使用--leak-check=yes,但我肯定也会检查其他选项。非常感谢你! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-01
  • 1970-01-01
  • 2012-03-17
  • 2011-02-15
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多