如何在源代码中查找内存泄漏
Posted
技术标签:
【中文标题】如何在源代码中查找内存泄漏【英文标题】:How to find memory leaks in source code 【发布时间】:2010-12-26 07:49:32 【问题描述】:如果已知应用程序泄漏内存(在执行时),有哪些方法可以在应用程序的源代码中定位此类内存泄漏错误。 我知道可以在这里使用某些解析器/工具(可能对代码进行静态分析),但是还有其他方法/技术可以做到这一点,特定于语言(C/C++)/平台?
【问题讨论】:
你试过 Valgrind 吗? 我认为这是重复的:***.com/questions/1502799/…。我不确定您是在寻找运行时检测还是静态代码分析。 这是一道作业题吗?请提供您尝试调试的具体情况,或至少说明该程序正在执行的工作。 是的。有用于此目的的外部工具。但是是否有任何通用的编程指南来定位这些错误,特定于语言(C/C++)? 将代码浸入水中并注意气泡。 【参考方案1】:Purify 会在这方面做得看起来很神奇
不仅是内存泄漏,还有许多其他类型的内存错误。
它通过实时检测您的机器代码来工作,因此您不需要源代码或使用任何特定选项进行编译。
只需使用 Purify 检测您的代码(执行此操作的最简单方法:CC="purify cc" make
),运行您的程序,并获得一个漂亮的 gui 来显示您的泄漏和其他错误。
适用于 Windows、Linux 和各种风格的 Unix。提供免费试用下载。
http://www.ibm.com/software/awdtools/purify
【讨论】:
【参考方案2】:就个人而言,我建议您使用clone_ptr
class 包装所有需要分配/解除分配内存的变量,该类在不再需要时为您执行所有内存解除分配。因此,您不必使用delete
。它与auto_ptr
非常相似。主要区别在于您不必处理棘手的所有权转让部分。更多关于clone_ptr
的信息和代码可以在here找到。
【讨论】:
【参考方案3】:内存泄漏检测有两种通用技术,动态分析和静态分析。
在动态分析中,您运行代码,然后一个工具分析运行以查看最后泄漏了哪些内存。动态分析往往非常准确,但只会正确分析您在工具中执行的特定执行。因此,如果您的某些泄漏仅针对特定输入发生,并且您没有使用该输入的测试,则动态分析将无法检测到这些泄漏。
静态分析分析源代码以创建所有可能的代码路径,并查看其中任何一个是否可能发生泄漏。虽然静态分析现在非常好,但它并不完美 - 您不仅可以获得假阴性(分析遗漏泄漏),还可以获得假阳性(该工具声称您有泄漏,而实际上没有泄漏)。
有许多动态分析工具,包括众所周知的工具Valgrind(开源但仅限于 x86 Linux 和 Mac)和Purify(商业但也可用于 Windows、Solaris 和 AIX)。***也有一个不错的 some other dynamic analysis tools 列表。
在静态分析方面,我认为值得的唯一工具是Coverity(商业)。再一次,***有一个many other static analysis tools 的列表。
【讨论】:
【参考方案4】:那里有 valgrind 和可能其他很棒的工具。 但我会告诉你我所做的,这对我来说非常有效,因为我多次在无法运行 valgrind 的环境中编写代码:
确保将每个分配与解除分配配对。我总是统计新闻或 malloc 并搜索删除或免费。 如果在 C++ 中并使用异常,请尝试将它们配对在构造函数/析构函数上。如果你喜欢冒险,或者不能把它们放在 Ctor/dtor 中,请确保没有异常可以使程序流不执行释放。 使用智能指针和 ptr 容器。 可以监控 alloc/dealloc 重写新或安装 malloc 处理程序。在某些时候,如果代码连续运行,很明显内存使用量是否会变得稳定并且不会无限制地增长,这将是最坏的泄漏情况。 小心使用永不收缩的容器,例如向量。有一些技巧可以缩小它们,将它们与空容器交换。【讨论】:
最重要的成语:RAII (en.wikipedia.org/wiki/RAII)。它确保正确的资源释放。 在嵌入式环境中,漫不经心地把东西放在堆栈上并不是一件容易的事。而且通常你有很多静态数据,所以你不能总是做 RAII。并非所有东西都是钉子。【参考方案5】:用于查找内存泄漏的通用指南并不多。幸运的是,防止大多数内存和其他资源的泄漏都有一个简单的指导方针:使用 RAII(资源获取即初始化),而且它们不会碰巧开始。这个名字是一个糟糕的描述,但如果你用谷歌搜索它,你应该会得到很多有用的结果。
【讨论】:
【参考方案6】:您还可以使用 purify 来检测内存泄漏。
【讨论】:
【参考方案7】:-
使用 -g 标志编译您的代码
下载 valgrind(如果您在 Linux 上工作)并使用 --leak-check=yes 选项运行它
我认为 valgrind 是完成这项任务的最佳工具。
对于 Windows:请参阅此主题:Is there a good Valgrind substitute for Windows?
【讨论】:
【参考方案8】:就手动操作而言,我认为没有任何既定做法。用细齿梳理代码,寻找new
s (alloc
s) 而没有对应的delete
s (free
s),就是这样。
【讨论】:
【参考方案9】:如果您使用智能指针并保存它们的表格,那么您可以对其进行分析以判断您仍在使用哪些内存。提供一个窗口来查看它,或者更常见的是,在程序终止之前将其流式传输到日志。
【讨论】:
以上是关于如何在源代码中查找内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章