Posts tagged memory leaks

How to iterate all MFC objects allocated on heap?

0


MFC is famous for memory leaks. Usually we add icing and cherrys to those leaks by adding our own leaks. Is there any mechanism to track those?

Well, if you’re object is a mfc object, which is derived from CObject, then MFC provides an iteration mechanism to iterate through your objects. You can use it to track the count of your objects in heap, you can dump selective objects… etc… etc… Well, how can you do it?


Use the api – AfxDoForAllObjects(). While calling we’ve to pass a function pointer of expected syntax, and for each CObject derived object in heap, the function will be called. See the sample to iterate all CDynLinkLibrary objects and to find its count.

// This function will be called as callback
// from AfxDoForAllObjects.
void DoForAllObjects(CObject* pObject, void* pContext)
{
    // Here context is the pointer to count variable.
    int* pCount = (int*) pContext;

    // Check whether the object is of type CDynLinkLibrary
    if( dynamic_cast<CDynLinkLibrary*>( pObject))
    {
        // Increment count.
        ++(*pCount);
    }

}

// Iterate objects.
void CDialogDlg::Iterate()
{
    // Iterate all CObject instances and get the
    // count of instances of CDynLinkLibrary objects.
    int DynLinkLibCount = 0;
    AfxDoForAllObjects( DoForAllObjects, &DynLinkLibCount );

}


You can utilize this for finding memory leaks, to find the count of instances of a particular class, you can dump objects of particular class, etc…

Well, one thing to remember – its only available in debug build. So take care! ;)


Targeted Audience – Intermediate.

How to detect Memory Leaks by using CRT?

1


Memory leaks are every programmers nightmare. Usually we used to use memory leak detection tools such as Numega BoundsChecker, Rational Purify to find memory leaks. But do you know that our C Runtime library have pretty good support for isolating memory leaks?

You’ve to enable memory leak tracking by defining constant – _CRTDBG_MAP_ALLOC and then call – _CrtDumpMemoryLeaks(). Now the leaks will be dumped to the Visual Studio output window. See the following code snippet.

// Declare this in header.
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
...
void DetectLeaks()
{
    // Create some leaks.
    CString* pString = new CString;
    BYTE* pBuffer = new BYTE[100];

    // Dump memory leaks to output window.
    _CrtDumpMemoryLeaks();
}

When you call _CrtDumpMemoryLeaks() the memory leak information will be dumped to the output window. For instance, see the dump for memory leaks that we’ve made in DetectLeaks().

Detected memory leaks!
Dumping objects ->
C:\Jijo\Studies\VC++\MFC\RabbitDlg\RabbitDlgDlg.cpp(183) : {194} normal block at 0x00294990, 100 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
C:\Jijo\Studies\VC++\MFC\RabbitDlg\RabbitDlgDlg.cpp(182) : {193} normal block at 0x00293B20, 4 bytes long.
 Data: <   _> 14 FB 8C 5F
...
Object dump complete.

The filename and line number of leak will be present in the dump. So easy, nah?


While creating your MFC applications, did you ever noticed a code block as follows in your files?

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

This is for debug information. By using this information, the _CrtDumpMemoryLeaks() keep track of the filename. If you comment out this, the filename will not be present in the dump which will make our task difficult. So never remove those line. I swear, they are really important! ;)


Targeted Audience – Intermediate

Go to Top