C/C++编译器中的内存泄漏检测

3

能否在C/C++编译器中构建堆内存泄漏的检测?例如,在语义分析期间,它可以简单地计算已分配的内存段(使用new/malloc或其他方式),以及每个调用delete/free的次数。然后在编译时发出警告。


1
如果我没记错的话,有一些库可以做到这一点。在大多数ABI库中,malloc()/free()是弱绑定函数,因此它们可以被您自己的版本或来自另一个库的版本所替换。 - πάντα ῥεῖ
你有一些静态分析工具,比如splint可以做到这一点...但是有些情况下,你只能在运行时(此时,你可能需要检查valgrind)轻松确定内存泄漏。 - pah
C++中完美的垃圾回收(=泄漏检测)等同于“停机问题”,因此通常无法解决。也就是说,有一些规则需要遵守,有一些可检测的热点需要检查。如果是新代码,请尝试仅使用托管指针,并且永远不要在没有weak_ptr的循环中。如果是旧代码,请进行性能分析。如果您可以编写代码,则可以执行有趣的操作,例如在构造函数中将实例注册到全局数组中,并在析构函数中删除。在许多情况下,一个额外的基类就足够了。 - lorro
根据标题,我以为你会说你已经通过valgrind运行了gcc并发现了内存泄漏或其他问题。 - Chris Beck
4个回答

1

0

我们的CheckPointer工具用于检测在运行时发生的指针管理错误,可以对MS或GCC C程序进行插装。

它能够检测到悬空指针、超出语言定义内存区域的指针(包括指向堆栈内部区域的指针)等问题。这些是Valgrind无法找到的问题,因为它认为整个堆栈都是指针有效引用的地方。同时,它也支持线程局部存储。

该工具会在可能报告此类错误的最早时间报告错误,从而使查找原因变得更加简单。

在执行结束时,它会生成一个已分配但未释放存储块的列表,以帮助跟踪内存泄漏。


0

嗯,也许你可以尝试制作它,但你应该考虑以下几点:

  • 你应该在整个程序模式下构建你的应用程序(否则你只能捕获一些非常琐碎的东西)。
  • 你应该对指针进行非常复杂的数据流分析 - 想象一下,你为某个对象分配了内存,然后将这个指针分配给另一个对象。而你只在程序的任何地方释放其中一个。或者你可以将这个指针放入某个容器中。
  • 在一个大型应用程序中可能会有成千上万的指针。因此,分析需要大量的内存和时间。比用户想要花费的时间和内存多得多。
  • 如果你进行相当便宜和快速的分析,那么它将是不准确的。所以你将不得不打印很多误报警告或只有对于最简单的事情才有精确的警告。

因此,作为学术研究,这可能非常有趣,但在现实生活中,我怀疑能够做出如此令人满意的质量分析。


0

嗯,有clang (LLVM) sanitizers。它们不是编译时的工具,但会在程序运行时添加运行时检测。

总体来说,对于依赖于输入数据行为的代码,完全静态地进行分析是不可能做到很好的。独立的静态分析工具有一些启发式算法可以追踪各种代码路径,这已经有点像动态的感觉了。

仅对代码进行仪器化并运行(或像valgrind一样模拟)在概念上更简单,尽管它会减慢执行速度。


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