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

Memory leak detection in C/C++ compiler

提问人:ibe 提问时间:7/6/2016 更新时间:9/27/2016 访问量:3437

问:

是否可以在 C/C++ 编译器中构建堆内存泄漏检测?例如,在最简单的形式中,在语义分析期间,它会简单地计算分配的内存段(使用/或其他方式)和/调用每个内存段。然后给出一个编译时警告。newmallocdeletefree

C++ C 编译器构造

评论

1赞 πάντα ῥεῖ 7/6/2016
IIRC 有一些可用的库这样做,/ 是大多数 ABI 库中的弱绑定函数,因此可以将它们替换为您自己的版本,或者来自另一个库的版本。malloc()free()
0赞 pah 7/6/2016
你有一些静态分析工具,比如可以这样做......但在某些情况下,您只能(轻松)确定运行时的内存泄漏(在这种情况下,您可能需要检查splintvalgrind)
0赞 lorro 7/6/2016
C++ 中的完美垃圾回收(=泄漏检测)等同于“停止问题”,因此通常无法解决。也就是说,有一些规则需要遵守,你应该检查一些可检测的热点。如果是新代码,请尝试仅使用托管 ptrs,并且永远不要有循环 w/o .如果是旧代码,请分析。如果您具有对代码的写入访问权限,则可以执行一些有趣的操作,例如在构造函数中将实例注册到全局数组,并在析构函数中删除实例。在许多情况下,额外的基类就足够了。weak_ptr
0赞 Chris Beck 7/6/2016
根据标题,我预计你会说你跑过并发现了内存泄漏或其他东西gccvalgrind

答:

1赞 Gregg 7/6/2016 #1

请参阅 C++ 核心指南,这是一个解析代码以查找与 GSL 标准的偏差的工具。该标准具有静态可执行的编码规则,可排除内存泄漏的可能性。

https://isocpp.org/blog/2015/09/bjarne-stroustrup-announces-cpp-core-guidelines

0赞 alexanius 7/13/2016 #2

好吧,也许你可以尝试这样做,但你应该考虑以下几点:

  • 您应该在整个程序模式下构建应用程序(在其他情况下,您只能捕获非常琐碎的事情)。
  • 您应该对指针进行非常复杂的数据流分析 - 想象一下,您为某个对象分配了内存,然后将此指针分配给另一个对象。而且你只在程序的任何地方释放其中一个。或者,您可以将此指针放入某个容器中。
  • 大型应用程序中可能有数十万个指针。因此,分析需要大量的内存和时间。远远超过用户想要花费的钱。
  • 如果你做一个相当便宜和快速的分析,它将是不准确的。因此,对于大多数简单的事情,您将不得不打印大量误报警告或仅打印确切的警告

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

0赞 Useless 7/13/2016 #3

好吧,有 clang (LLVM) 消毒剂。它们不是编译时,而是将运行时检测添加到发出的程序中。

一般来说,对于行为依赖于输入的代码,不可能完全静态地做好工作。独立的静态分析工具有一些启发式方法,用于跟踪各种代码路径,这已经是动态的了。

仅仅检测代码并运行它(或像 valgrind 一样模拟)在概念上更简单,尽管它确实会减慢执行速度。

0赞 Ira Baxter 9/27/2016 #4

我们的 CheckPointer 工具可检测 MS 或 GCC C 程序,以查找运行时发生的各种指针管理错误。

它检测悬空指针,即跳出它们所针对的语言定义的内存区域的指针,包括指向堆栈内区域的指针(这些是 Valgrind 无法找到的问题,因为它认为整个堆栈是指针引用的有效位置)。它还处理线程本地存储。

它会在可以报告此类错误的最早时间报告错误,这使得查找原因变得更加简单。

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