127

In unmanaged C/C++ code, what are the best practices to detect memory leaks? And coding guidelines to avoid? (As if it's that simple ;)

We have used a bit of a silly way in the past: having a counter increment for every memory allocation call and decrement while freeing. At the end of the program, the counter value should be zero.

I know this is not a great way and there are a few catches. (For instance, if you are freeing memory which was allocated by a platform API call, your allocation count will not exactly match your freeing count. Of course, then we incremented the counter when calling API calls that allocated memory.)

I am expecting your experiences, suggestions and maybe some references to tools which simplify this.

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
prakash
  • 58,901
  • 25
  • 93
  • 115
  • 1
    you searh valgrin (for linux) or deleaker (for windows), also look visual leak detector... – John Smith Feb 22 '12 at 20:00
  • for finding memory leaks check here:http://theunixshell.blogspot.com/2013/11/finding-memory-leaks-on-solaris-is-no.html – Vijay Nov 29 '13 at 09:01
  • In terms of avoiding leaks the following post has some advice: [http://stackoverflow.com/questions/27492/c-memory-management](http://stackoverflow.com/questions/27492/c-memory-management) – tonylo Sep 06 '08 at 09:16
  • I used this one with visual studio to detect mem leak. http://www.codeproject.com/KB/applications/visualleakdetector.aspx – tiboo Nov 12 '10 at 03:16
  • I asked this question here: [http://stackoverflow.com/questions/25730/what-is-the-best-free-memory-leak-detector-for-a-cc-program-and-its-plug-in-dlls](http://stackoverflow.com/questions/25730/what-is-the-best-free-memory-leak-detector-for-a-cc-program-and-its-plug-in-dlls) and had great success with [Visual Leak Detector](http://www.codeproject.com/KB/applications/visualleakdetector.aspx). – Jim Buck Sep 06 '08 at 10:57
  • http://www.saunalahti.fi/~tarmpika/diagnostic/ I had tried so many memory leak detectors that it's difficult to count them all. Some of them crashed, some of them produced invalid results, some of them simply did not help. Eventually I've made my own leak detector, but invested so much effort into it - so made it non-free for timebeing. Managed / native / 32 & 64-bit architectures supported. – TarmoPikaro Feb 09 '16 at 17:36
  • Web page went down, but now I've decided to publish source code of my tool - here it is: https://sourceforge.net/projects/diagnostic/ – TarmoPikaro Sep 22 '16 at 20:30
  • I don't think this is a bad question, as it doesn't ask "suggest a tool for.." Obviously people will use tools to do it. – CashCow Nov 24 '16 at 12:04

29 Answers29

81

If your C/C++ code is portable to *nix, few things are better than Valgrind.

Good Person
  • 1,437
  • 2
  • 23
  • 42
Jordi Bunster
  • 4,886
  • 3
  • 28
  • 22
  • 1
    Valgrind also now works on OS X, so linux is not your only option. – Michael Anderson Oct 12 '10 at 03:01
  • 1
    Valgrind for Linux (and OS X). If you use windose - deleaker - best of all! – John Smith Dec 12 '11 at 18:12
  • @JordiBunster : Nice ! But runtime based. With a large code base *(written in C in ly case)* you will mainly test your program for the way it had been designed. An attacker can the several thousands required hours at reading the code in order to find a memory leak exploit. I would have expected an automated tool for source code analysis similar to what exist for JavaScript. – user2284570 Oct 02 '15 at 13:50
66

If you are using Visual Studio, Microsoft provides some useful functions for detecting and debugging memory leaks.

I would start with this article: https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.140).aspx

Here is the quick summary of those articles. First, include these headers:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

Then you need to call this when your program exits:

_CrtDumpMemoryLeaks();

Alternatively, if your program does not exit in the same place every time, you can call this at the start of your program:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

Now when the program exits all the allocations that were not free'd will be printed in the Output Window along with the file they were allocated in and the allocation occurrence.

This strategy works for most programs. However, it becomes difficult or impossible in certain cases. Using third party libraries that do some initialization on startup may cause other objects to appear in the memory dump and can make tracking down your leaks difficult. Also, if any of your classes have members with the same name as any of the memory allocation routines( such as malloc ), the CRT debug macros will cause problems.

There are other techniques explained in the MSDN link referenced above that could be used as well.

Dusty Campbell
  • 3,146
  • 31
  • 34
  • A note about this method: it appears that this only works if you are using pure C with malloc and free. The detailed report which includes line numbers is not created if you are using c++'s new and delete. – Zach Feb 12 '09 at 14:48
  • 2
    @Zach: actually you can get this to work too (for any code you actually compile yourself, anyway) - see accepted answer in http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/5a98b72e-c927-4f4b-9441-8a73575dfb10/ – Roman Starkov Feb 09 '10 at 01:43
  • Will this work in release mode too ? – J V Jul 21 '15 at 06:14
  • 1
    @user3152463 No. According to the documentation, it will only work for the debug build: https://msdn.microsoft.com/en-us/library/e5ewb1h3(v=vs.71).aspx – Dusty Campbell Jul 22 '15 at 05:50
  • This line is wrong: #define CRTDBG_MAP_ALLOC It should be: #define _CRTDBG_MAP_ALLOC – Fallso Jun 22 '16 at 08:10
  • If you're using C++, you can make a class that its destructor calls `_CrtDumpMemoryLeaks`, and make a static instance of it. the destructor will be called when the application exits – David Haim Mar 11 '17 at 10:28
37

In C++: use RAII. Smart pointers like std::unique_ptr, std::shared_ptr, std::weak_ptr are your friends.

roschach
  • 8,390
  • 14
  • 74
  • 124
Leon Timmermans
  • 30,029
  • 2
  • 61
  • 110
  • 1
    and std:vector is a great replacement for when arrays (buffers) are deallocated in the same function they are allocated. – KJAWolf Sep 30 '08 at 13:47
  • 4
    At least std::auto_ptr and boost::shared_ptr are still susceptible to leaks. – Jasper Bekkers Dec 22 '08 at 23:55
  • 5
    Only if you use them incorrectly, though I should admit that for std::auto_ptr using it incorrectly is quite easy. – Leon Timmermans Jan 08 '09 at 14:23
  • 2
    Whilst this is good advice for coding standards, it does not answer the question. Even using shared_ptr can lead to leaks with circular dependences. And you can have "leaks" with unlimited caching strategies, which apply even to garbage-collected languages. – CashCow Nov 24 '16 at 12:03
  • @CashCow: you are correct. While I haven't seen it yet in practice, that's probably because I'm using them sparingly. To quote the answer below, "Use pointers only when absolutely necessary". – Leon Timmermans Nov 24 '16 at 15:42
29

As a C++ Developer here's some simply guidelines:

  1. Use pointers only when absolutely necessary
  2. If you need a pointer, doublecheck if a SmartPointer is a possibility
  3. Use the GRASP Creator pattern.

As for the detection of memory leaks personally I've always used Visual Leak Detector and find it to be very useful.

Huppie
  • 11,263
  • 4
  • 32
  • 34
  • 2
    Visual Leak Detectore moved to new site http://vld.codeplex.com/ – KindDragon Apr 04 '11 at 21:19
  • VLD is a REALLY nice leak detector - I totally recommend it for everyone using VC++ – Javid Sep 09 '16 at 17:55
  • 1
    +1 for point #1. This is absolutely the fundamental thing. Unfortunately, it looks to me like some of the biggest "C++" libraries tend to eschew stack allocation and/or RAII in favour of Pointers Everywhere, often for no discernible reason. So, they end up being 'C with Classes', not actual C++. – underscore_d Jan 17 '17 at 01:11
16

I've been using DevStudio for far too many years now and it always amazes me just how many programmers don't know about the memory analysis tools that are available in the debug run time libraries. Here's a few links to get started with:

Tracking Heap Allocation Requests - specifically the section on Unique Allocation Request Numbers

_CrtSetDbgFlag

_CrtSetBreakAlloc

Of course, if you're not using DevStudio then this won't be particularly helpful.

Chris
  • 135
  • 2
  • 7
Skizz
  • 69,698
  • 10
  • 71
  • 108
10

I’m amazed no one mentioned DebugDiag for Windows OS.
It works on release builds, and even at the customer site.
(You just need to keep your release version PDBs, and configure DebugDiag to use Microsoft public symbol server)

Tal
  • 1,759
  • 1
  • 12
  • 22
  • 3
    Link no longer works, try here for documentation: http://support.microsoft.com/kb/2580960 and here to download: http://www.microsoft.com/en-us/download/details.aspx?id=26798 – JPaget Sep 18 '12 at 20:04
7

Visual Leak Detector is a very good tool, altough it does not supports the calls on VC9 runtimes (MSVCR90D.DLL for example).

Hernán
  • 4,527
  • 2
  • 32
  • 47
  • 1
    This tool is really perfect! It saves you the trouble to use the _CrtDumpMemoryLeaks(); and friends, as described in MSDN. Just one include and it exposes everything! Even works in old C libraries! – m_pGladiator Feb 18 '10 at 10:43
  • The new version (for VS2013) is here: http://vld.codeplex.com/ – Dženan Jul 17 '14 at 16:04
7

Microsoft VC++ in debug mode shows memory leaks, although it doesn't show where your leaks are.

If you are using C++ you can always avoid using new explicitly: you have vector, string, auto_ptr (pre C++11; replaced by unique_ptr in C++11), unique_ptr (C++11) and shared_ptr (C++11) in your arsenal.

When new is unavoidable, try to hide it in a constructor (and hide delete in a destructor); the same works for 3rd party APIs.

Robert
  • 767
  • 8
  • 17
Serge
  • 7,706
  • 5
  • 40
  • 46
4

There are various replacement "malloc" libraries out there that will allow you to call a function at the end and it will tell you about all the unfreed memory, and in many cases, who malloced (or new'ed) it in the first place.

Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
4

If you're using MS VC++, I can highly recommend this free tool from the codeproject: leakfinder by Jochen Kalmbach.

You simply add the class to your project, and call

InitAllocCheck(ACOutput_XML)
DeInitAllocCheck()

before and after the code you want to check for leaks.

Once you've build and run the code, Jochen provides a neat GUI tool where you can load the resulting .xmlleaks file, and navigate through the call stack where each leak was generated to hunt down the offending line of code.

Rational's (now owned by IBM) PurifyPlus illustrates leaks in a similar fashion, but I find the leakfinder tool actually easier to use, with the bonus of it not costing several thousand dollars!

John Sibly
  • 22,782
  • 7
  • 63
  • 80
  • 1
    I checked out leakfinder and it looks okay, but just FYI it won't work as-is for x64 because it contains inline assembly. – Zach Feb 12 '09 at 14:45
3

Never used it myself, but my C friends tell me Purify.

Iain Holder
  • 14,172
  • 10
  • 66
  • 86
3

If you're using Visual Studio it might be worth looking at Bounds Checker. It's not free, but it's been incredibly helpful in finding leaks in my code. It doesn't just do memory leaks either, but also GDI resource leaks, WinAPI usage errors, and other stuff. It'll even show you where the leaked memory was initialized, making it much easier to track down the leak.

Herms
  • 37,540
  • 12
  • 78
  • 101
2

I would recommend using Memory Validator from software verify. This tool proved itself to be of invaluable help to help me track down memory leaks and to improve the memory management of the applications i am working on.

A very complete and fast tool.

Fabien Hure
  • 644
  • 3
  • 7
  • 17
2

Are you counting the allocs and frees by interpolating your own syscall functions which record the calls and then pass the call to the real function?

This is the only way you can keep track of calls originating from code that you haven't written.

Have a look at the man page for ld.so. Or ld.so.1 on some systems.

Also do Google LD_PRELOAD and you'll find some interesting articles explaining the technique over on www.itworld.com.

Rob Wells
  • 36,220
  • 13
  • 81
  • 146
2

I think that there is no easy answer to this question. How you might really approach this solution depends on your requirements. Do you need a cross platform solution? Are you using new/delete or malloc/free (or both)? Are you really looking for just "leaks" or do you want better protection, such as detecting buffer overruns (or underruns)?

If you are working on the windows side, the MS debug runtime libraries have some basic debug detection functionality, and as another has already pointed out, there are several wrappers that can be included in your source to help with leak detection. Finding a package that can work with both new/delete and malloc/free obviously gives you more flexibility.

I don't know enough about the unix side to provide help, although again, others have.

But beyond just leak detection, there is the notion of detecting memory corruption via buffer overruns (or underruns). This type of debug functionality is I think more difficult than plain leak detection. This type of system is also further complicated if you are working with C++ objects because polymorhpic classes can be deleted in varying ways causing trickiness in determining the true base pointer that is being deleted. I know of no good "free" system that does decent protection for overruns. we have written a system (cross platform) and found it to be pretty challenging.

Mark
  • 10,022
  • 2
  • 38
  • 41
2

I'd like to offer something I've used at times in the past: a rudimentary leak checker which is source level and fairly automatic. I'm giving this away for three reasons:

  1. You might find it useful.

  2. Though it's a bit krufty, I don't let that embarass me.

  3. Even though it's tied to some win32 hooks, that should be easy to alleviate.

There are things of which you must be careful when using it: don't do anything that needs to lean on new in the underlying code, beware of the warnings about cases it might miss at the top of leakcheck.cpp, realize that if you turn on (and fix any issues with) the code that does image dumps, you may generate a huge file.

The design is meant to allow you to turn the checker on and off without recompiling everything that includes its header. Include leakcheck.h where you want to track checking and rebuild once. Thereafter, compile leakcheck.cpp with or without LEAKCHECK #define'd and then relink to turn it on and off. Including unleakcheck.h will turn it off locally in a file. Two macros are provided: CLEARALLOCINFO() will avoid reporting the same file and line inappropriately when you traverse allocating code that didn't include leakcheck.h. ALLOCFENCE() just drops a line in the generated report without doing any allocation.

Again, please realize that I haven't used this in a while and you may have to work with it a bit. I'm dropping it in to illustrate the idea. If there turns out to be sufficient interest, I'd be willing to work up an example, updating the code in the process, and replace the contents of the following URL with something nicer that includes a decently syntax-colored listing.

You can find it here: http://www.cse.ucsd.edu/~tkammeye/leakcheck.html

Thomas Kammeyer
  • 4,457
  • 21
  • 30
2

For Linux: Try Google Perftools

There are a lot of tools that do similar alloc/free counting, the pros of Goolge Perftools:

  • Quite fast (in comparison to valgrind: very fast)
  • Comes with nice graphical display of results
  • Has other useful capabilities: cpu-profiling, memory-usage profiling...
Weidenrinde
  • 2,152
  • 1
  • 20
  • 21
2

The best defense against leaks is a program structure which minimizes the use of malloc. This is not only good from a programming perspective, but also improves performance and maintainability. I'm not talking about using other things in place of malloc, but in terms of re-using objects and keeping very explicit tabs on all objects being passed around rather than allocating willy-nilly like one often gets used to in languages with garbage collectors like Java.

For example, a program I work on has a bunch of frame objects representing image data. Each frame object has sub-data, which the frame's destructor frees. The program keeps a list of all frames that are allocated, and when it needs a new one, checks a list of unused frame objects to see if it can re-use an existing one rather than allocate a new one. On shutdown, it just iterates through the list, freeing everything.

Dark Shikari
  • 7,941
  • 4
  • 26
  • 38
1

At the top of this list (when I read it) was valgrind. Valgrind is excellent if you are able to reproduce the leak on a test system. I've used it with great success.

What if you've just noticed that the production system is leaking right now and you have no idea how to reproduce it in test? Some evidence of what's wrong is captured in the state of that production system, and it might be enough to provide an insight on where the problem is so you can reproduce it.

That's where Monte Carlo sampling comes into the picture. Read Raymond Chen's blog article, “The poor man's way of identifying memory leaks” and then check out my implementation (assumes Linux, tested only on x86 and x86-64)

http://github.com/tialaramex/leakdice/tree/master

tialaramex
  • 3,761
  • 1
  • 21
  • 23
1

Working on Motorola cell phones operating system, we hijacked memory allocation library to observe all memory allocations. It helped to find a lot of problems with memory allocations. Since prevention is better then curing, I would recommend to use static analysis tool like Klockwork or PC-Lint

Dan
  • 5,929
  • 6
  • 42
  • 52
aku
  • 122,288
  • 32
  • 173
  • 203
  • splint is a newer replacement for lint. – Mark Kegel Oct 12 '08 at 12:43
  • @user14788: Gimpel's PC-Lint product is much more modern than the old Unix `lint`. It has many checks specific to C++, which afaik splint does not. See the link in the answer (which I renamed from Lint to PC-Lint). – Dan Oct 12 '10 at 02:57
1

At least for MS VC++, the C Runtime library has several functions that I've found helpful in the past. Check the MSDN help for the _Crt* functions.

Dan Shield
  • 1,358
  • 7
  • 14
1

Paul Nettle's mmgr is a long time favourite tool of mine. You include mmgr.h in your source files, define TEST_MEMORY, and it delivers a textfile full of memory problems that occurred during a run of your app.

Josh Matthews
  • 12,816
  • 7
  • 36
  • 39
1

General Coding Guideline:

  • Resources should be deallocated at the same "layer" (function/class/library) where they are allocated.
  • If this is not possible, try to use some automatic deallocation (boost shared pointer...)
Weidenrinde
  • 2,152
  • 1
  • 20
  • 21
1

Memory debugging tools are worth their weight in gold but over the years I've found that two simple ideas can be used to prevent most memory/resource leaks from being coded in the first place.

  1. Write release code immediatly after writing the acquisition code for the resources you want to allocate. With this method its harder to "forget" and in some sense forces one to seriously think of the lifecycle of resources being used upfront instead of as an aside.

  2. Use return as sparringly as possible. What is allocated should only be freed in one place if possible. The conditional path between acquisition of resource and release should be designed to be as simple and obvious as possible.

Einstein
  • 4,450
  • 1
  • 23
  • 20
0

A nice malloc, calloc and reallloc replacement is rmdebug, it's pretty simple to use. It is much faster to then valgrind, so you can test your code extensively. Of course it has some downsides, once you found a leak you probably still need to use valgrind to find where the leak appears and you can only test mallocs that you do directly. If a lib leaks because you use it wrong, rmdebug won't find it.

http://www.hexco.de/rmdebug/

quinmars
  • 11,175
  • 8
  • 32
  • 41
0

Most memory profilers slow my large complex Windows application to the point where the results are useless. There is one tool that works well for finding leaks in my application: UMDH - http://msdn.microsoft.com/en-us/library/ff560206%28VS.85%29.aspx

Sean
  • 1,373
  • 2
  • 14
  • 26
  • I don't see why slowdown makes the results useless. Surely memory that is leaked is leaked regardless of the speed at which the program runs. The point of these tools is to find leaks, so where's the problem? Did it run so slowly that you couldn't physically get it to cover all code paths in order to profile them? – underscore_d Jan 17 '17 at 01:08
0

Valgrind is a nice option for Linux. Under MacOS X, you can enable the MallocDebug library which has several options for debugging memory allocation problems (see the malloc manpage, the "ENVIRONMENT" section has the relevant details). The OS X SDK also includes a tool called MallocDebug (usually installed in /Developer/Applications/Performance Tools/) that can help you to monitor usage and leaks.

jbl
  • 2,710
  • 3
  • 18
  • 13
0

Detect:

Debug CRT

Avoid:

Smart pointers, boehm GC

DrPizza
  • 17,882
  • 7
  • 41
  • 53
-1

Mtrace appears to be the standard built-in one for linux. The steps are :

  1. set up the environment variable MALLOC_TRACE in bash
    MALLOC_TRACE=/tmp/mtrace.dat
    export MALLOC_TRACE;
  2. Add #include <mcheck.h> to the top of you main source file
  3. Add mtrace(); at the start of main and muntrace(); at the bottom (before the return statement)
  4. compile your program with the -g switch for debug information
  5. run your program
  6. display leak info with
    mtrace your_prog_exe_name /tmp/mtrace.dat
    (I had to install the mtrace perl script first on my fedora system with yum install glibc_utils  )
paperhorse
  • 4,095
  • 2
  • 22
  • 12