如何避免C / C ++中的内存泄漏

时间:2010-06-06 05:34:46

标签: c++ c memory memory-leaks

我可以使用哪些提示来避免应用程序中的内存泄漏?在我当前的项目中,我使用了一个工具“INSURE ++”来查找内存泄漏并生成报告。

除了该工具之外,还有任何方法可以识别内存泄漏并克服它。

6 个答案:

答案 0 :(得分:10)

这有三种主要方式。

首先是不首先创建内存泄漏。防御性编程技术在这里非常宝贵。有关此问题的摘要或excellent presentation中的相关章节,请参阅此Secure C Coding。我对C语言比C ++更熟悉,但我知道C ++的smart pointers在这里很有用。

第二种方法静态分析,它试图检测源代码中的错误。此类别中的原始工具是 lint ,现在已经过时了。据我所知,最好的工具是商业性的,例如coverty。但是,有些free tools do exist

第三种方法是在运行时检测内存泄漏,例如 INSURE ++ Valgrind非常好,强烈推荐。它可能有助于捕获您已经介绍过的错误。如果你有一个具有良好代码覆盖率的测试套件,它将特别有用。

答案 1 :(得分:7)

对于C,一个好的代码组织会有所帮助。即不要在代码库中调用malloc()和free()。将它们集中到两个函数中,然后您有一个单点用于所有检查。最简单的可能是计算成功的呼叫,并在程序退出时检查它们是否均衡。

static unsigned long mymem_count_alloc = 0;
static unsigned long mymem_count_free  = 0;

void *mymem_alloc (size_t size)
{
    void *p;

    p = malloc(size);
    if (p)
    {
        mymem_count_alloc++;
    }
    else
        error logging/handling/signaling

    return (p);
}

void mymem_free (void *p)
{
    if (p)
    {
        free(p);
        mymem_count_free++;
    }
}

void mymem_check (void)
{
    if (mymem_count_alloc != mymem_count_free)
        error alert
}

您可以针对不同的数据结构继续此操作。无论您需要为字符串分配内存,请使用mystr_alloc和mystr_free。等等。当以这种方式检测到泄漏时,您可以快速缩小范围。

答案 2 :(得分:2)

我们是在讨论找到泄漏的工具,还是编写代码以避免泄漏的方法?

对于前者,上面提到的valgrind,或者IBM工具的Rational套件,如果你有许可证。 Dobbs博士推荐了CompuWare的BoundsChecker,但那是2002年。

对于后者,请参阅:

C++ idiom to avoid memory leaks?

http://www.cprogramming.com/tutorial/memory_debugging_parallel_inspector.html

http://scottmcpeak.com/memory-errors/

http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

答案 3 :(得分:2)

智能指针在自动记录对象生命周期方面非常有用:

http://ootips.org/yonat/4dev/smart-pointers.html

尽可能使用堆栈分配的对象在其相关范围内而不是new / delete。

像valgrind这样的工具有一些开销,可能会减慢你的运行速度。如果您知道您的代码库以及可能出现的泄漏类型,您可以定位特定的类并实现更轻的权重检查(即使只是一个简单的对象计数,您在退出时检查为零)。然后,可以使用这些轻量级检查来激励您在触发时进行更广泛的valgrind调试会话。

答案 4 :(得分:1)

使用智能指针,例如std::shared_ptr<t>(C ++ 0x),std::tr1::shared_ptr<t>(TR1)或boost::shared_ptr<t>。当然,这个解决方案只适用于C ++ - 你可以在C中独立使用。

答案 5 :(得分:0)

避免或检测?要避免,首先检测并尝试了解其中的位置和原因......另一种方法可能是使用GC库,如the one described here,但可能存在其他(可能更好)的库。