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.
In C++: use RAII. Smart pointers like
std::unique_ptr
,std::shared_ptr
,std::weak_ptr
are your friends.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.
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.
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.
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
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.
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