【问题标题】:How to find memory leaks in source code如何在源代码中查找内存泄漏
【发布时间】:2010-12-26 07:49:32
【问题描述】:

如果已知应用程序泄漏内存(在执行时),有哪些方法可以在应用程序的源代码中定位此类内存泄漏错误。
我知道可以在这里使用某些解析器/工具(可能对代码进行静态分析),但是还有其他方法/技术可以做到这一点,特定于语言(C/C++)/平台?

【问题讨论】:

  • 你试过 Valgrind 吗?
  • 我认为这是重复的:stackoverflow.com/questions/1502799/…。我不确定您是在寻找运行时检测还是静态代码分析。
  • 这是一道作业题吗?请提供您尝试调试的具体情况,或至少说明该程序正在执行的工作。
  • 是的。有用于此目的的外部工具。但是是否有任何通用的编程指南来定位这些错误,特定于语言(C/C++)?
  • 将代码浸入水中并注意气泡。

标签: c++ c memory-leaks


【解决方案1】:

Purify 会在这方面做得看起来很神奇

不仅是内存泄漏,还有许多其他类型的内存错误。

它通过实时检测您的机器代码来工作,因此您不需要源代码或使用任何特定选项进行编译。

只需使用 Purify 检测您的代码(执行此操作的最简单方法:CC="purify cc" make),运行您的程序,并获得一个漂亮的 gui 来显示您的泄漏和其他错误。

适用于 Windows、Linux 和各种风格的 Unix。提供免费试用下载。

http://www.ibm.com/software/awdtools/purify

【讨论】:

    【解决方案2】:

    就个人而言,我建议您使用clone_ptrclass 包装所有需要分配/解除分配内存的变量,该类在不再需要时为您执行所有内存解除分配。因此,您不必使用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】:
            1. 使用 -g 标志编译您的代码
            2. 下载 valgrind(如果您在 Linux 上工作)并使用 --leak-check=yes 选项运行它

            我认为 valgrind 是完成这项任务的最佳工具。

            对于 Windows:请参阅此主题:Is there a good Valgrind substitute for Windows?

            【讨论】:

              【解决方案8】:

              就手动操作而言,我认为没有任何既定做法。用细齿梳理代码,寻找news (allocs) 而没有对应的deletes (frees),就是这样。

              【讨论】:

                【解决方案9】:

                如果您使用智能指针并保存它们的表格,那么您可以对其进行分析以判断您仍在使用哪些内存。提供一个窗口来查看它,或者更常见的是,在程序终止之前将其流式传输到日志。

                【讨论】:

                  猜你喜欢
                  • 2016-12-10
                  • 1970-01-01
                  • 2021-08-14
                  • 2011-07-02
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-10-11
                  相关资源
                  最近更新 更多