Advertisement

Fixing memory leaks

Started by June 28, 2001 11:33 PM
10 comments, last by Ratman 23 years, 7 months ago
quote:
Original post by Stoffel
We''ve had the unfortunate experience once or twice of using container that automatically grow without bounds and release memory once they''re destroyed. The problem is, if they''re really growing without bounds, you can overflow your memory and kill your system resources, even if you deallocate the memory at the end of the program --this does not show up in bounds checker or any "leak detection" utility.



Actually I believe you can do that with Midnight''s code (or by writing your own memory manager). It doesn''t just detect memory leaks, but also array bounds being overwritten, memory consumtion, etc, etc. Since all memory allocation must go through that code, you can generate stats on just about anything, including printing out the most memory consumed at any point the in program with which allocations consumed the most memory and the exact line of code that allocation took place. You may have to write a few new functions to do this, but it''s not hard.

Although I will conceed that Performance Monitor is a great tool. It allows you to quickly and easily see if certain memory problems exist, among other things, then you can use your own tools to track the problem down.


- Houdini

- Houdini
One approach that''s worked well for me is to use an abstract allocator interface for all memory allocation, i.e. something with unimplemented methods for malloc, realloc, free, and so forth. The default implementation for this does nothing but punt down to the actual malloc/free/etc, but you can set it up to use other allocators for more extensive integrity checks, or other operations including leak tracking.

Some other leak-tracking methods are able to report the location of an allocation, but when you''re inside a small frequently-used function then it''s difficult to track down the real cause of the leak based on this information alone. A more descriptive call stack would provide this information, though, and Win32''s dbghelp functions like StackWalk, SymGetSymFromAddr, etc. are very useful for this. For my leak-tracking allocator, i do a stack walk for the most recent 8 calls on the stack, and store the addresses with the allocated memory block. Sure it''s an extra 32 bytes consumed per allocation, but it''s only necessary when you''re trying to track down leaks. The allocator also keeps track of all the allocated blocks in a doubly linked list (another 8 bytes per allocation, so it''s 40 bytes total). As blocks are allocated/freed, the linked list is modified accordingly. Finally, when I exit the application, the allocator dumps out all remaining blocks in the list, along with the call stack at the time of the allocation. Makes tracking down leaks *very* easy. I''ve seen this same idea mentioned recently in some postmortem in Game Developer magazine, and apparently it worked well for them too.

If you want to know more about StackWalk and the dbghelp library, take a look a Robbins'' excellent book "Debugging Applications". You can use this kind of functionality not only for tracking leaks, but also for assertions (as the author does), and even fatal exceptions, which is *very* handy for debugging. Just make sure if you''re using C++ and try/catch blocks that you grab the call stack before C++''s exception handling mechanism takes over... see the little-documented MSVC++ function _set_se_translator for a hint on doing this).

And note that all of this works in release builds as well as debug.

--
Chris Hargrove
Senior Programmer, Legend Entertainment

This topic is closed to new replies.

Advertisement