Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ memory
I have a C++ application which contains a memory-leak, although I am using "Leakdiag" and "LDGrapher", I can't locate where the leak is?!
I'm also using "_CrtDumpMemoryLeaks()" function which give me results like this:
    Detected memory leaks!
    Dumping objects ->
    {657} normal block at 0x00D93B98, 52 bytes long.
     Data: < N   N          > D8 4E D9 00 D8 4E D9 00 00 00 00 00 CD CD CD CD
    {656} normal block at 0x00D93AF0, 108 bytes long.
     Data: <(        ;  (   > 28 F0 12 00 00 00 00 00 98 3B D9 00 28 F0 12 00
    {655} normal block at 0x00D94ED8, 52 bytes long.
     Data: < ;   ;          > 98 3B D9 00 98 3B D9 00 CD CD CD CD CD CD CD CD
    f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\occcont.cpp(923) : {641} normal block at 0x00D92100, 12 bytes long.
     Data: <            > F6 06 0A 00 00 00 00 00 00 00 00 00
How can I locate the real location of the memory leak?
Posted 31-May-12 2:24am
Edited 31-May-12 2:27am
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

The way I used, when confronted with a leak, was all manual - no tools.
The important thing is: you don't have to find the leak in order to fix it.
Look for malloc() calls (and friends: calloc, realloc, strdup): replace as many of them as possible by stack variables, and all the others by smart pointers (std::auto_ptr,. for instance). Wherever you keep a heap allocation, add a comment with a really good excuse: the maximum size of a buffer is not known until run time, or the function is actually a factory whose purpose is to allocate and initialize an object.
Look for places where new and delete are used as if they were malloc and free. Use std::auto_ptr instead.
Look for global pointers. Destroy them.
 
In the end you'll have not only fixed the leak, but you'll have improved overall code quality.
 
Just my two bits,
  Permalink  
v2
Comments
Aescleal at 1-Jun-12 6:46am
   
While I agree with a lot of the advice here (and it's a lot better than most textbooks and lecturers give out) I would add:-
 
- never use std::auto_ptr. If that's all you've got then grab a copy of boost
- for variable sized buffers std::vector works pretty well
- immediately assign anything that has ownership transferred to your code to either std::unique_ptr or std::shared_ptr
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

The quickest way to avoid memory leaks is to not make them in the first place. There's really no reason to manually manage memory any more, it's a bit of a mug's game.
 
That said there are a few of things you can try without digging into the standard library source code (nv3 knows more than I do about the structure of the runtime heap):
 
- Find all the places you're using new. When you find them:-
 
(a) work out if the object can be stack allocated instead (Java programmers in particular are buggers for newing everything and not using RAII). If you can replace them with stack objects do so!
 
(b) replace any raw pointers that represent ownership with std::unique_ptr, std::shared_ptr or std::vector
 
(c) remove all the deletes that that the compiler is now complaining about
 
- Instrument new and delete. Make a memory block counter class which you can declare in scopes to see if a leak potentially occurs in there. Use it in your unit tests and it'll show up if an object is leaking a contained object.
 
- Instrument selected class's constructors and destructor. Select them by choosing ones that are about the same size as the blocks that are being lost. Keep a running total of objects constructed and subtract the number of objects destructed. If over the run of your program you find there are excess objects constructed you can narrow the problem down to where objects of that class are newed.
 
- Related to the previous one if you've got a lost memory block have a look at the first word of the dumped block. If it looks like a pointer it could be the address of the class's vtable - if you have any virtual function. If you're feeling brave you might be able to correlate the address with a class using a map file (/MAP:filename on the linker command line).
 
- If you want to get the memory layout of a particular class or all classes in a translation unit (handy for looking at your blocks and seeing if you recognise anything in there and finding the vtable ptr) use /d1reportAllClassLayout or /dreportSingleClassLayout on the compiler command line
 
Er, that's about it from me, hope you sort it out soon.
  Permalink  
Comments
Espen Harlinn at 31-May-12 15:12pm
   
Well answered :-D
pwasser at 1-Jun-12 0:04am
   
Very good. I have found it useful to set all heap pointers to null when declared and also when freed. So before new is called test the pointer is null. This catches a lot of dangling pointers which can be hard to find and are insidious.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

The numbers in curly braces like {657} give you a hint where and when it happens. These are the allocation request numbers. So every single allocation gets a new number and by this number you can track things.
 
If you can reproduce the memory leak in DEBUG mode and the leaks occur always with the same request numbers you can use the following technique:
 
- set a breakpoint in dbgheap.c in function _heap_alloc_dbg on the line that says:
 
     lRequest = _lRequestCurr;
 
Instead of looking for that file in your VC++ installation you can equally well set a breakpoint an arbitrary new statement and drill down with step-into until you arrive at function _heap_alloc_dbg. Then find the above line and set a breakpoint there.
 
- make this a conditional breakpoint that only triggers for the request number you are looking for
 
- run your program; hopefully you will land on your breakpoint
 
- look at the call stack and find out what actually initiated this memory allocation request
 
It's not a really easy technique, but very helpful in some of the hard cases.
  Permalink  
Comments
Aescleal at 31-May-12 8:55am
   
This strikes me as one of the courts of last resort when debugging memory allocation problems but a handy one to know when nothing else works.
nv3 at 31-May-12 9:02am
   
Yes, it is kind of a last resort, but has helped me out in a couple of cases. Thanks Ash.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

You will have to use some profiling tool to do that. search and you will find some.
 
Also, check this article. it is also pretty good: Easy Detection of Memory Leaks[^]
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 5

Add the following macro into your source files, after the header includes. When in _DEBUG mode, you'll get the file and line number where the leak was allocated, reported in the output window.
 
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
  Permalink  
v2
Comments
pwasser at 1-Jun-12 0:09am
   
Does this work in all cases?
JackDingler at 1-Jun-12 8:56am
   
If leak is in the module that contains the macro, it does.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 6

A way that I found and use to detect memory leak. You can add following code in header file and overload global new and delete. In debug mode, you can easily identify where the memory leak happens.
 
struct LogInfo
{
char file[100];
int line;
};
 
//Create a global map : Key will be memory pointer address and value will be LogInfo object
 
#ifdef _DEBUG
inline void* operator new (unsigned int size, const char* file, int line)
{
void* ptr = (void*)malloc(size);
//Insert value in map
return ptr;
};
 
inline void operator delete(void* p)
{
//Remove value from map
free(p);
};
#endif
 

#ifdef _DEBUG
#define DEBUG_NEW new(__FILE__, __LINE__)
#else
#define DEBUG_NEW new
#endif
#define new DEBUG_NEW
 

And at the end of your program you can dump your map object to identify where memory leaks has been occured.
  Permalink  
Comments
JackDingler at 31-May-12 14:16pm
   
Microsoft already provides this capability in their libraries.
Mohibur Rashid at 31-May-12 22:37pm
   
Wow I have gave that solution in this forum before. and someone deleted my answer, now you are giving the same answer again. let see

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 195
1 ProgramFOX 130
2 Maciej Los 105
3 Sergey Alexandrovich Kryukov 105
4 Afzaal Ahmad Zeeshan 82
0 OriginalGriff 6,564
1 Sergey Alexandrovich Kryukov 6,048
2 DamithSL 5,228
3 Manas Bhardwaj 4,717
4 Maciej Los 4,150


Advertise | Privacy | Mobile
Web01 | 2.8.1411022.1 | Last Updated 31 May 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100