Click here to Skip to main content
Click here to Skip to main content

Catching memory leaks

By , 4 Oct 2000
 
  • Download demo project - 7 Kb
  • Introduction

    I would like share with you some experience in catching memory leaks. In most case it is a long processe and required additional tools like PurifyNT or BoundsChecker. Actually, catching simple memory leaks is possible by using the Microsoft exported functionality.

    In a simple case you should add several lines to 'StdAfx.h'

    #ifdef _DEBUG
       #define _CRTDBG_MAP_ALLOC // include Microsoft memory leak detection procedures
       #define _INC_MALLOC	     // exclude standard memory alloc procedures
    #endif
    

    Note: it should be before the 'include' directives.

    In the enclosed example you will find an example with a memory leak. To see how it works you should run program under the debugger. When the program finishes you will see in the the 'Output' window, 'Debug' tab the following message.

    Detected memory leaks!
    Dumping objects -> D:\Projects\CrtDbg\CrtDbg.cpp(25) : {53} normal block at 0x002F26C0, 10 bytes long.
    Data: <MemoryLeak> <MEMORYLEAK> 4D 65 6D 6F 72 79 4C 65 61 6B 
    Object dump complete.
    

    In more advanced memory management cases you should look in the 'AfxMem.cpp' file in MFC source directory. File contents plenty of memory management functions.

    I have written a class CMemDiff that wraps CMemoryState and helps track memory leaks. Just include the MemDiff files in your project. A global variable of type CMemDiff is declared and it's constructor and destructor will check the state of your memory at the start and end of your program and report any leaks.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    About the Author

    Audrius Vasiliauskas
    Business Analyst
    Lithuania Lithuania
    Member
    No Biography provided

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    You must Sign In to use this message board.
    Search this forum  
        Spacing  Noise  Layout  Per page   
    GeneralSoooooooo Cooooooolmemberinternal10 Jun '04 - 16:28 
    Rose | [Rose] You've got my 5!!!Cool | :cool:
     
    Sing when we're programming.
    GeneralRe: An extremely useful tipmemberpeterboulton9 Dec '04 - 1:24 
    This is indeed a good tip.
     
    However, even when you have DEBUG_NEW defined you can occasionally still run into problems with the dump not telling you which line the errant block was allocated. Here's an enhancement to the tip for these situations.
     
    Sometimes the number in curly braces varies each time you run your program, however carefully you try to follow the same path. Yet you only find the correct number after it's too late. This makes things a little hard!
     
    My tip is that generally you should have a rough idea where the leak is. You can narrow it down to an extent by commenting out function calls etc., but when this breaks down you can use the following approach.
     
    In my code, I'd worked out (by commenting it out) that the memory leak was always somewhere in the CGraphCtrl::SaveGraphSettings(pOpenFptr); call.
     
    Here's how you get the debugger to break on the line responsible for creating the memory leak:
     
    long allocReqNum;
    char *my_pointer;
    my_pointer = (char*)malloc(10);
    _CrtIsMemoryBlock(my_pointer, 10, &allocReqNum, NULL, NULL);
    free(my_pointer); // Breakpoint on first run and note value of allocReqNum
     

    _CrtSetBreakAlloc(allocReqNum+1); // Comment out on first debug run
     
    CGraphCtrl::SaveGraphSettings(pOpenFptr);
     
    When I run it first time I comment out the _CrtSetBreakAlloc call and set a break point after the _CrtIsMemoryBlock call. I then note the allocation number in allocReqNum when the break point is hit.
     
    When the program finishes I look at the memory leaks dump and note the number in curly braces. (If the number in curly braces is lower you need to look earlier in your code's execution!)
     
    Now I can calculate the offset value to add to allocReqNum in the _CrtSetBreakAlloc call - in my example it's '1' - the difference between the number in curly braces in the memory dump and the value I got from akkicReqNum. So I uncomment out the _CrtSetBreakAlloc call and adjust the 'allocReqNum+1' to the correct offset number.
     
    And, finally, now my program will break at the correct allocation point - the one which allocates the memory which is not freed by my program.
     
    Hope this is all clear - if not let me know and I'll try to pen something a little fuller.
     
    I must be slow - it's taken me years, plus the earlier tip, to think of this approach. But hopefully DEBUG_NEW will work for most situations.

    GeneralRe: An extremely useful tipmemberRainKing Fool4 Oct '05 - 15:43 
    Great tip Peter!
     
    Dealing with big legacy apps it's sometimes difficult to get an associated source file in a memory leak dump. This tip (why didn't I think of that D'Oh! | :doh: ) is a definite help!
     
    Thank you for taking the time to share it with us
    Smile | :)
     
    Pierre

    Generalabout VC7memberMuhammad Ahmed5 Feb '04 - 0:14 
    hello :
    can u please tell me where to use the code..
    #ifdef _DEBUG
    #define _CRTDBG_MAP_ALLOC // include Microsoft memory leak detection procedures
    #define _INC_MALLOC // exclude standard memory alloc procedures
    #endif
     
    in VC7, i tried to do ot in stdafx.h but i get errors...
    thanks
     
    ahmed
    GeneralNot Getting the path where actully memory leak occuringmemberJaymin5 Aug '03 - 2:26 
    Hello,
     
    I am getting memory leak while terminating the application. as shown below.
     
    --> Detected memory leaks!
    0 bytes in 0 Free Blocks.
    261307 bytes in 8802 Normal Blocks.
    1381 bytes in 7 CRT Blocks.
    0 bytes in 0 Ignore Blocks.
    784 bytes in 24 Client Blocks.
    Largest number used: 6200457 bytes.
    Total allocations: 39746600 bytes.
     
    --> Finished track memory leaks
     
    My application is too big and it is not a good idea to look in everywhere , and from this application i found that it shows exact path where memory leak is occuring. but it does not show me. can you help me to detect memory leak where excatly it is occuring.

     
    Thank you very much
    GeneralMemory LeaksussSivakumar R27 Mar '03 - 23:59 
    It is indeed a simpler way to detect memory leaks. But I don't have any idea about the following lines. I hope I have solved all the memory leak problem in my application. But still I am getting the following lines and getting error when I am closing my application. This would be a great help for me if you suggest me to analyse the following lines.
     
    Thanks in advance.
     
    HEAP[DialTest.exe]: Invalid Address specified to RtlValidateHeap( 1940000, 1944c80 )
    memory check error at 0x01944C9C = 0xEE, should be 0xFD.
    memory check error at 0x01944C9D = 0xFE, should be 0xFD.
    memory check error at 0x01944C9E = 0xEE, should be 0xFD.
    memory check error at 0x01944C9F = 0xFE, should be 0xFD.
    First-chance exception in DialTest.exe (MSVCRTD.DLL): 0xC0000005: Access Violation.
    Detected memory leaks!
    Dumping objects ->
    c:\program files\microsoft visual studio\vc98\include\crtdbg.h(552) : {82} normal block at 0x01945328, 14512 bytes long.
    Data: < > 1F 00 00 00 00 C0 02 10 00 00 00 00 CD CD CD CD
    c:\program files\microsoft visual studio\vc98\include\crtdbg.h(552) : {68} normal block at 0x01944C58, 4 bytes long.
    Data: < > 00 00 00 00
    {66} client block at 0x01944B08, subtype 0, 64 bytes long.
    a CDynLinkLibrary object at $01944B08, 64 bytes long
    {59} client block at 0x01942E18, subtype 0, 64 bytes long.
    a CDynLinkLibrary object at $01942E18, 64 bytes long
    Object dump complete.
    Generalabout call stackmemberNing Cao7 Jan '03 - 15:55 
    Could anyone tell me how to find the Call stack information from my PROGRAM?
     
    I would like to have a function such as DumpCallStack(). So, in my program, I can write the following:
     
    void sub()
    {
    int k = 10;
    #ifdef _DEBUG
    DumpCallStack();
    #endif
    }
     
    int main()
    {
    sub();
    return 0;
    }
     
    If this feature is available, debugging memory leaks will be easier than the following message:
    c:\program files\microsoft visual studio\vc98\include\crtdbg.h(552) : {60776} normal block at 0x016472E0, 4 bytes long.
    Data: < d > B8 BF 64 01
     

    Thanks ahead!
     
    Best Regards,
    Yours,
    Ning Cao
    GeneralRe: about call stackmemberMike Nordell7 Jan '03 - 16:25 
    Ning Cao wrote:
    Could anyone tell me how to find the Call stack information from my PROGRAM?
     
    Have you done your Googling and searched CP itself before asking? Well, maybe it's easy to miss stuff like this.
    GeneralRe: about call stackmemberNing Cao7 Jan '03 - 16:35 
    I have searched the keyword "Call Stack" in google.
    It gives out many links but most of them are regarding the "Call Stack Window".
     
    Best Regards,
    Yours,
    Ning Cao
    GeneralRe: about call stackmemberKita24 Jun '03 - 21:33 
    You can search AfxDumpStack sample in MSDN.

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Permalink | Advertise | Privacy | Mobile
    Web04 | 2.6.130523.1 | Last Updated 5 Oct 2000
    Article Copyright 2000 by Audrius Vasiliauskas
    Everything else Copyright © CodeProject, 1999-2013
    Terms of Use
    Layout: fixed | fluid