静态分析可以检测内存泄漏吗?

Can static analysis detect memory leaks?

我很久以前就获得了 ISTQB 认证,我记得它有以下区别:
-静态分析:对源代码执行,检测无法访问的代码,未分配的值等
-动态分析:可以检测内存泄漏等,需要执行(profiling)。

但是当我今天搜索时,我可以看到各种网站和资源都提到静态分析也能够检测内存泄漏。

所以我想知道,静态分析真的能做到这一点吗?如果是这样,那么动态分析在结果方面有何不同?

静态分析能够以预期会导致内存泄漏的构造形式检测内存泄漏的可能性。但是,它无法在运行时检测到实际内存泄漏的存在,因为它从不检查代码库的执行。

一个很好的 designed/implemented 静态分析工具可以检测出许多情况,其中一些代码 必须 有泄漏,仅通过分析代码。 Coverity/Prevent 等工具可以很好地做到这一点。

此类工具还可以检测到许多 可能 存在泄漏的情况(图灵 tarpit 使其无法确定)。关于该工具是否应该报告这些存在着巨大的争论,因为它们可能是误报,而误报是在浪费程序员的时间。 [更糟糕的是:如果程序员将她的时间浪费在几个误报上,s/he 通常会完全放弃使用该工具,现在甚至连真正检测到的错误的价值都丢失了]。

动态分析工具通常可以在泄漏发生在运行时的那一刻判断是否发生了泄漏。 (想象一个指向堆的指针保存在一个局部变量中,并且该局部变量超出范围)。 (请参阅我们的 CheckPointer 动态分析工具工具,它几乎可以检测运行时遇到的每个 stack/heap allocation/pointer 误用错误。

我很确定静态分析器可以捕获:

void MyFunction()
{
    char * leakable = new char[1000];
}

所以,你的问题的答案不言自明 "Yes"。

一个更有趣的问题是它能否捕获更细微的泄漏。答案是 "often yes" 如果它可以访问所涉及的所有源代码或所涉及方法的 contract 的表示(即:如果评论说:调用者负责释放返回的对象”,那么静态分析器可能无法捕捉到它,但如果相同的概念用代码表达(或者可以通过分析代码得出),静态分析器有时可以发现问题。

作为静态分析器的开发人员之一,我可以说搜索内存泄漏的问题对于 SCA 来说是一项极其复杂的任务,有时甚至是不可能完成的任务。静态分析器在这个领域确实很薄弱,我们不应该对它们抱有太大期望。动态分析器在搜索内存泄漏方面要强大得多,如果有找到它们的任务,那么你应该考虑动态分析,而不是静态分析。

是的,静态分析器能够找到简单的内存泄漏案例。但在实践中,当代码很复杂并且程序的不同部分的内存为 free/allocated 时,你会遇到内存泄漏。因此,静态分析确实效率不高。