Ways to avoid Memory Leaks in C/C++

2019-02-01 13:27发布

问题:

What are some tips I can use to avoid memory leaks in my applications? In my current project I use a tool "INSURE++" which finds the memory leak and generate the report.

Apart from the tool is there any method to identify memory leaks and overcome it.

回答1:

There are three main ways of doing this.

The first is to not create memory leaks in the first place. Defensive programming techniques are invaluable here. See this excellent presentation for a summary of this issues, or the relevant chapter in Secure C Coding. I am more familiar with C than C++, but I understand that C++'s smart pointers are useful here.

A second approach static analysis, which attempts to detect errors in your source-code. The original tool in this category is lint, which is now sadly outdated. The best tools, as far as I know, are commercial such as coverty. However, some free tools do exist.

The third approach is to detect memory leaks at runtime, like INSURE++ does. Valgrind is excellent here and highly recommended. It may help catch bugs you've already introduced. It is especially helpful if you do have a test suite that has good code coverage.



回答2:

For C, a good code organization helps. I.e. don't throw calls to malloc() and free() all over your codebase. Centralize them into two functions, then you have one single point for all the checkings. The simplest one could be to count the successful calls and check at program exit that they are balanced.

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
}

You can continue this for the different data structures. Whereever you need to allocate memory for a string, use mystr_alloc and mystr_free. And so on. When a leak is detected this way, you can quickly narrow it down.



回答3:

Smart pointers can be very helpful in automating the bookkeeping of object lifetimes:

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

Where possible, use stack allocated objects inside of their relevant scopes instead of new/delete.

Tools like valgrind have some overhead and can slow down your runs. If you know your codebase and the kinds of leaks that tend to arise, you can target specific classes and implement lighter weight checks (even just a simple object count that you check against zero when you quit). These lightweight checks can then be used to motivate you into doing a more extensive valgrind debugging session when they are triggered.



回答4:

Are we talking tools to find leaks, or ways to code to avoid them?

For the former, the above mentioned valgrind, or Rational suite of IBM tools if you have a license to that. Dr. Dobbs recommended CompuWare’s BoundsChecker but that was 2002.

For the later, see:

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



回答5:

Use a smart pointer, such as std::shared_ptr<t> (C++0x), std::tr1::shared_ptr<t> (TR1), or boost::shared_ptr<t>. Of course this solution only works with C++ -- you're on your own in C.



回答6:

To avoid or to detect? To avoid, first detect and try to understand where and why... Another way could be the use of a GC library, like the one described here, but other (maybe better) libraries may exist.