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

Detecting Memory Leaks using the CrtDbg Library

, 19 Mar 2010
Rate this:
Please Sign up or sign in to vote.
The CrtDbg Library provides APIs which can be used to detect memory leaks

Abstract

Memory is a very important aspect for an application to run. Applications that leak large amounts of memory or leak progressively may display symptoms ranging from poor (and gradually decreasing) performance to running out of memory completely. Worse, a leaking program may use up so much memory that it causes another program to fail, leaving the user with no clue to where the problem truly lies. In addition, even harmless memory leaks may be symptomatic of other problems.

When an application is very big, it could have 100+ files and 1000+ functions and it would be tough to find memory leaks in the application, so we can use the CrtDbg Library APIs to find the memory leaks in that application.

For memory leak detection, we have so many tools available in the market, but you need to pay a lot for them. This article talks about a C Runtime Library which is free and available with all Windows OSs, and is called the CrtDbg Library. This library provides APIs which can be used to detect memory leaks.

Audience

Win32/Win64 developers who want to detect memory leaks in their applications.

Memory Leak Samples

// 1.
class test
{
  public: test()
  {
     a = new int;
  }
 ~test()
 {
    delete a;
 }
private:
  int *a;
};

test *t = new test[10];
// When we are not calling delete t then destructor will not be called 
// and hence this code is having memory leak.

// 2.
{
  // no delete called for str having 20 bytes allocated
  char* str = new char[20];
  strcpy(str,"memory leak");
}

Introduction

Memory Allocation on Stack

int number = 10;

Whenever a number variable goes out of scope, the memory allocated for the variable will be deallocated automatically.

Memory Allocation on Heap

int * number = new int[10];

The above line allocates 10 integer sizes on the heap (40 bytes if the integer size is 4 bytes), and we have to call the delete function to deallocate the memory allocated on the heap. delete [] number is required to delete the memory allocated on the heap in the above example. Sometimes, we forget to call delete for the variables allocated on the heap, and we can use C Runtime Library (CRT) functions to find the leaks in a given code.

Using the Code

We can use CrtDbg library functions to detect the memory leaks in our application.

The technique for locating memory leaks involves taking snapshots of the application's memory state at key points. The CRT library provides a structure type, _CrtMemState, which you can use to store a snapshot of the memory state:

_CrtMemState s1, s2, s3;

To take a snapshot of the memory state at a given point, pass a _CrtMemState structure to the _CrtMemCheckpoint function. This function fills in the structure with a snapshot of the current memory state:

_CrtMemCheckpoint(&s1);

After calling _CrtMemCheckpoint(&s1), code can be written in which we can detect the memory leak. (_CrtMemCheckpoint can be used anywhere in the code.)

After writing your code, use _CrtMemCheckpoint( &s2 ) to take another snapshot of the memory at that time; after that, you can call _CrtMemDifference(&s3, &s1, &s2).

_CrtMemDifference compares two memory states s1 and s2, and returns their differences (debug version only). _CrtMemDifference(&s3, &s1, &s2) will return 0 if there is no memory leak between the s1 and s2 memory checkpoints, and returns 1 if the code written between the checkpoints s1 and s2 has a memory leak.

If _CrtMemDifference returns 1, then we can call _CrtDumpMemoryLeaks() to dump the memory leak. The memory leak will be shown in the Debugger window of the IDE (Visual Studio) with the line number of the memory allocation which has not been deallocated.

If you want the file name and the line number of the memory leak in your application, then overload the operator new macro with another macro which will use the file name and the line number.

#define new new(_CLIENT_BLOCK,__FILE__, __LINE__)

By using the above code, the _CrtDumpMemoryLeaks function will show the file name and the line number of the memory leak in your application.

And if you want the memory leak information to be logged into a file, then use the following API with the required options.

_CrtSetReportMode

Function prototype:

int _CrtSetReportMode(  int reportType, int reportMode );

Report type: _CRT_WARN, _CRT_ERROR, and _CRT_ASSERT

  • _CRT_WARN: Warning, messages, and information that do not need immediate attention
  • _CRT_ERROR: Errors, unrecoverable problems, and issues that require immediate attention
  • _CRT_ASSERT: Assertion failures

Report mode: _CRTDBG_MODE_DEBUG, _CRTDBG_MODE_FILE, _CRTDBG_MODE_WNDW, _CRTDBG_REPORT_MODE

  • _CRTDBG_MODE_DEBUG: Writes the message to the debugger's output window
  • _CRTDBG_MODE_FILE: Writes the message to a user-supplied file handle. _CrtSetReportFile should be called to define the specific file or stream to use as the destination.
  • _CRTDBG_MODE_WNDW: Creates a message box to display the message along with Abort, Retry, and Ignore buttons.
  • _CRTDBG_REPORT_MODE: Returns reportMode for the specified reportType: _CRTDBG_MODE_FILE, _CRTDBG_MODE_DEBUG, _CRTDBG_MODE_WNDW.

_CrtSetReportFile

After specifying _CRTDBG_MODE_FILE with _CrtSetReportMode, you can specify the file handle to receive the message text.

Function prototype:

_HFILE _CrtSetReportFile(  int reportType, _HFILE reportFile );

So if you want to log a memory leak found in your application to a log file, then create a log file using the CreateFile Win32 API and then use _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE) and after that _CrtSetReportFile((_CRT_WARN, FileHandle). The file handle will be returned by the CreateFile Win32 API (which is used to create a file).

Sample Code

int main()
{
    _CrtMemState &s1,&s2,&s3;
    // This line will take a snapshot
    // of the memory allocated at this point.
    _CrtMemCheckPoint(&s1);
    // your code
    // this line will take another snapshot
    // of the memory allocated at this point.
    _CrtMemCheckPoint(&s2);
    if (_CrtMemDifference(&s3,&s1,&s2))
    // _CrtMemDifference will calculate the memory allocation,
    // which has not been deallocated done between s1 and s2
    // memory check points.
    {
        _CrtDumpMemoryLeaks();
        // This line will dump the memory leak found between s1 and s2
        // memory check points.
    }
    return 0;
}

How Can We Avoid Getting Memory Leaks?

Make sure that:

  1. You correctly use 'new'/'delete' and 'new[]'/'delete[]' (also 'malloc'/'free').
  2. Pointers don't go out of scope before memory is released.
  3. If you allocate memory in a loop, you release it in each iteration.

Summary

Memory is a very important aspect to run any application, so avoid memory leaks while writing code by following the above guidelines, and get your code reviewed by other technical members of your team, or use the CrtDbg library APIs. The CrtDbg library works only in Debug mode, so you cannot use it to find memory leaks for Release mode applications.

Attached to this article is a sample application which uses CrtDbg APIs to find memory leaks. This sample application can be opened using Visual Studio 2005. Compile the application in Debug mode and execute it. It will show the memory leaks in the Debugger window of the Visual Studio 2005 IDE.

History

  • 17th March, 2010: Initial post
  • 19th March, 2010: Article updated

License

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

About the Author

naveenonnet
Team Leader Kony, Hyderabad
India India
No Biography provided

Comments and Discussions

 
QuestionMisleading comment about _CrtDumpMemoryLeaks PinmemberJohn Schroedl22-Aug-11 7:42 
AnswerRe: Misleading comment about _CrtDumpMemoryLeaks PinmemberJohn Schroedl22-Aug-11 7:50 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 19 Mar 2010
Article Copyright 2010 by naveenonnet
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid