?
Solved

Tracking down memory leaks in StrCore.cpp by using _CrtSetBreakAlloc

Posted on 2007-03-23
8
Medium Priority
?
3,244 Views
Last Modified: 2011-10-03
I’m trying to track down some memory leaks in StrCore.cpp by using _CrtSetBreakAlloc in my watch window and I can’t get it to work.

The memory leak looks like this and there are hundreds of them:
f:\sp\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {8164} normal block at 0x196336A8, 272 bytes long.
 Data: <, ?x    ÿ       > 2C 08 3F 78 00 00 00 00 FF 00 00 00 01 00 00 00

Maybe I’m not typing it into my Watch window correctly, I tried alot of different ways.  Here is exactly what I have been trying.

Thes give “CXX0017: Error: symbol “_CrtSetBreakAlloc” not found”:
_CrtSetBreakAlloc
__p__crtBreakAlloc()
_CrtSetBreakAlloc(8164)
_CrtSetBreakAlloc(8164);
{,,msvcrtd.dll}_crtBreakAlloc
_CrtSetBreakAlloc(8164)

These give “CXX0036: Error: bad context {…} specification”:
{msvcrtd.dll}*__p__crtBreakAlloc(8164)
{,,msvcrtd.dll}*__p__crtBreakAlloc(8164)
{,,msvcrtd.dll}_crtBreakAlloc(8164)
{,,msvcrtd.dll}_crtBreakAlloc(8164)

Any ideas on how I can fix this or how I can track down these memory leaks?
0
Comment
Question by:bigsteve87
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
8 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 18782309
You can only use '_CrtSetBreakAlloc()' in debug builds when you add it to your code like in

#include <malloc.h>
#include <crtdbg.h>

void main( )
{
        long allocReqNum;
        char *my_pointer;

        /*
         * Allocate "my_pointer" for the first
         * time and ensure that it gets allocated correctly
         */
        my_pointer = malloc(10);
        _CrtIsMemoryBlock(my_pointer, 10, &allocReqNum, NULL, NULL);

        /*
         * Set a breakpoint on the allocation request
         * number for "my_pointer"
         */
        _CrtSetBreakAlloc(allocReqNum+2);
        _crtBreakAlloc = allocReqNum+2;

        /*
         * Alternate freeing and reallocating "my_pointer"
         * to verify that the debugger halts program execution
         * when it reaches the allocation request
         */
        free(my_pointer);
        my_pointer = malloc(10);
        free(my_pointer);
        my_pointer = malloc(10);
        free(my_pointer);
}

Typing it in your debugger's watch window won't help you here.

0
 
LVL 86

Expert Comment

by:jkr
ID: 18782328
BTW - an easier way to find your leaks:

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 number where the allocation occured.

(Ref.: http:Q_21009673.html)
0
 

Author Comment

by:bigsteve87
ID: 18782774
I tried the easier way where you define _DBG_NEW but it came up with alot of errors.
 I'll try the _CrtIsMemoryBlock solution now.  

Here are the errors it came up with:
3>C:\Program Files\Microsoft Visual Studio 8\VC\include\xdebug(32) : error C2365: 'operator new' : redefinition; previous definition was 'function'
3>C:\Program Files\Microsoft Visual Studio 8\VC\include\xdebug(32) : error C2491: 'new' : definition of dllimport data not allowed
0
Technology Partners: 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 86

Expert Comment

by:jkr
ID: 18782818
Hm, just checked with a project that uses this (also VC8), that should work like:

#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 // _DEBUG
0
 

Author Comment

by:bigsteve87
ID: 18782941
Sry, I changed it and am still getting the same errors.
0
 
LVL 11

Expert Comment

by:DeepuAbrahamK
ID: 18783121
Add this below your header file:

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

Best Regards,
DeepuAbrahamK
0
 
LVL 86

Expert Comment

by:jkr
ID: 18783363
Actually, in order for the above to work, you need to locate that section and comment it out:

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

since that is mostlikely to cause the compile error.
0
 

Author Comment

by:bigsteve87
ID: 18783447
Thanks guys, I was able to track it down using  _crtBreakAlloc.
I tried using the other method with the modifications with no luck.  Could have to do with my project being a mess because I'm in the process of converting from VC98 to VS2005.
0

Featured Post

Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

Question has a verified solution.

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

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

800 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