?
Solved

VC++ Memory Leak Detection not working

Posted on 2009-02-09
18
Medium Priority
?
1,698 Views
Last Modified: 2013-12-12
Hi,
My big win32 VC++ solution has many memory leaks :). But by default, Visual Studio 2005 shows only the memory allocation numbers and blocks. No filename and line number.

I gone through all the memory detection pages of Microsoft and tried what's written there. Though it worked in a small sample win32 applicatiion I tried, but not in my big solution. I have included the lines

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

at the end of the stdafx.h file in each project. (a few projects my solution uses are plain win32 projects that don't have stdafx.h and cpp. I included the above lines in a header file which every source file uses in those projects). But still when I close my application, the debugger shows only the same info, nothing more: no filename, line number etc.

Then I thought of setting a "breakpoint at memory allocation number"(http://msdn.microsoft.com/en-us/library/w2fhc9a3(VS.80).aspx) so that I will anyway know where the leak is occurring. But even that is not making the debugger break at those locations. Why would it happen?

Any simpler way of doing these things? Any way that I don't have to include these things in every file but just one?


Thanks a lot for your help !!!
0
Comment
Question by:piyush_soni
  • 8
  • 4
  • 2
  • +1
16 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 23592431
You can get the line numbr and file information from the C runtime directly, e.g.:

Add the following to a central header file:

#ifdef _DEBUG
#ifndef _DBG_NEW

#include <crtdbg.h>

inline void* __operator_new(size_t __n) {
     return ::operator new(__n,_NORMAL_BLOCK,__FILE__,__LINE__);
}
inline void* _cdecl operator new(size_t __n,const char* __fname,int __line) {
     return ::operator new(__n,_NORMAL_BLOCK,__fname,__line);
}
inline void _cdecl operator delete(void* __p,const char*,int) {
     ::operator delete(__p);
}

#define _DBG_NEW new(__FILE__,__LINE__)
#define new _DBG_NEW


#endif // _DBG_NEW
#else

#define __operator_new(__n) operator new(__n)

#endif

Then, add

               int tmpFlag;

               // Get the current state of the flag
               // and store it in a temporary variable
               tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );

               // Turn On (OR) - Keep freed memory blocks in the
               // heap’s linked list and mark them as freed
               tmpFlag |= _CRTDBG_LEAK_CHECK_DF;

               // Set the new state for the flag
               _CrtSetDbgFlag( tmpFlag );


to your app's start code and call

               _CrtDumpMemoryLeaks ();


to before the program ends and you'll get the line numbers where the allocations occured.

(Ref.: http:Q_21009673.html)
0
 
LVL 2

Author Comment

by:piyush_soni
ID: 23593728
Ok, I can add a new header file in the solution. But then does that really need to be included in EACH cpp file I have in the Solution? It's tooo big and has many different projects inside. Some have stdafx (in that condition I'd add your new header file at the end of stdafx.h) and some don't have...
0
 
LVL 86

Expert Comment

by:jkr
ID: 23593762
If you want to catch all leaks in all files - yes ;o)

The good news is that you could just add that to 'StdAfx.h', which will by included by all files anyway.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Author Comment

by:piyush_soni
ID: 23593787
I had also tried just setting a breakpoint at the memory allocation number using this page:
http://msdn.microsoft.com/en-us/library/w2fhc9a3(VS.71).aspx

But even that didn't do anything and when I close my application those memory allocation numbers are seen..
0
 
LVL 2

Author Comment

by:piyush_soni
ID: 23593881
There are about 30 stdafx.h files in the different projects in the solution. Anyway, I'm adding that in all of them let's see.

But what about the code to be added in the cpp file? The application starts in one project and loads the dlls of all these different projects. Will it do if I only include that code in my WinMain() method in this startup project?
0
 
LVL 86

Expert Comment

by:jkr
ID: 23593900
Are you using the shared version of MS' runtime, i.e. msvcrt.dll? If so, that will work fine from 'WinMain()'.
0
 
LVL 12

Expert Comment

by:Gideon7
ID: 23593941

#include <crtdbg.h>
void EnableMemoryChecking()
{
 int oldFlags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
   _CrtSetDbgFlag(oldFlags | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
}
0
 
LVL 2

Author Comment

by:piyush_soni
ID: 23594268
I am getting only 2851 errors after removing the ones the other thread you replied was getting.
(That is, commented wherever
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

was being used)



These errors are ranging from

"Error    43    error C2660: 'BControlledMemoryObject::operator new' : function does not take 3 arguments    <filepath>

(It seems a project or two had overridden new & delete operators. )
to even vc8 files:

Error    631    error C2027: use of undefined type 'Font'    c:\program files\microsoft visual studio 8\vc\platformsdk\include\gdiplusgraphics.h    1376    
And a lot of others :(
0
 
LVL 2

Author Comment

by:piyush_soni
ID: 23594279
Gideon7,
Is the solution you are telling need to be included only in one file? Where if yes?
0
 
LVL 12

Expert Comment

by:Gideon7
ID: 23594288
Include anywhere, call once early.
0
 
LVL 86

Expert Comment

by:jkr
ID: 23594375
Gideon7, this is literally the same flag as I posted earlier... nothing else.

Oh, and overloaded operators could be a problem here - let me think...
0
 
LVL 2

Author Comment

by:piyush_soni
ID: 23594422
Also, it seems I cannot comment out "DEBUG_NEW" from the files which I said above. One big project is manually using DEBUG_NEW instead of new to allocate memory it seems. (using the defines:
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

)
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 23604792
>>>> The good news is that you could just add that to 'StdAfx.h', which will by included by all files anyway.

I don't think that this will work as StdAfx.h is a 'precompiled header'  (PCH) which will not be really included but the 'compiled' stdafx.cpp will be used to add all the necessary code of the stdafx.h and all the symbols to any cpp which has the PCH option switched on.

Because of that the wizard puts the sequence

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

explicitly into each generated cpp file *below* #include stdafx.h.

Unfortunately the above macros won't work together with

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

as there were duplicate definitions by that. Furthermore the stdlib.h and crtdbg.h already were included in stdafx.h so that they won't included again and so that the setting of the macro has no effect.

You can try to put these 3 statements as very first includes into the stdafx.h and make a rebuild. But I assume you will get a preprocessor error doing so cause the afx.h (or similar *afx.h) MUST be included first or the preprocessor breaks with error.

I would suggest you to use the

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

for each cpp file and put them above the first implemented function and below all includes what should work as long as you didn't include any other overload of operator 'new'.

0
 
LVL 2

Accepted Solution

by:
piyush_soni earned 0 total points
ID: 23688658
I tried this but again .... it doesn't work and I am fed up now. The problem is there are so many projects, so many files in each project and some have overridden this new operator, and some have used the above three lines (#define _CRT and two includes one) and some this DEBUG_NEW thing. Moreover, instead of using DEBUG only after changing it through the precompiler they manually use DEBUG_NEW and I don't know why. I have given up and am trying to use this tool called DevPartner (and interestingly even that is not working after a big show off of its installation and integration with VS 2005 and internal windows etc. - but I guess re-installing that could help. Don't know anyway.)


0
 
LVL 2

Author Comment

by:piyush_soni
ID: 23744579
I don't know. Whatever decision the moderator takes about the points will be accepted. Though I had known these solutions separately, but probably my solution and projects are too typical for any of them to work here. Let's close it.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 25315578
I would recommend to PAQ the q. rather than deleting them. There are a few valuable comments posted which didn't help here but might help other times.

Regards, Alex
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever run into that annoying problem where the computer won't boot?  Wouldn't it be great if you had a tool that would make that disk boot again?  I have found one tool that works more often than not ...
Want to know how to use Exchange Server Eseutil command? Go through this article as it gives you the know-how.
An overview on how to enroll an hourly employee into the employee database and how to give them access into the clock in terminal.
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question