Memory leaks and how to detect them

Detect memory leaks in a C/C++ Application.

Memory leaks and how to detect them

1. What is a memory leak?

When an object is allocated memory on heap and the allocated memory is not deleted/freed when the application exits, it becomes a memory that is no longer needed but is not released. This is called a memory leak.

An example of a memory leak -

int main() {
   int* p = new int(5);
   return 0;
}

In the above example, p is pointing to an integer allocated on heap with value 5. 2_memory_leak.png When the application exits, this memory on heap holding the value 5 is not released and is a memory leak.

2. How to detect a memory leak?

In this blog, we will be using a Microsoft Visual C++ specific header. There are 2 important questions here -

Are there any memory leaks?

You can check for overall memory leaks in the application using _CrtDumpMemoryLeaks()

int main() {
   int *p = new int[10];
   _CrtDumpMemoryLeaks();
   return 0;
}

When you debug this application, you will see the following in the 'Output' window: 3_mem_leak.png Here 4 x 10, 40 bytes of memory allocated on heap was not released and has been detected as a memory leak.

In large applications, it can be difficult to figure out where exactly the memory leak is happening even after you have detected that there are memory leaks.

Where are the leaks?

You can take snapshots of the application memory around the code where you suspect a memory leak and then inspect the difference between the 2 snapshots. This can be done as follows:

int main() {
    _CrtMemState s1, s2, s3;
    _CrtMemCheckpoint(&s1);
    int *p = new int;
    _CrtMemCheckpoint(&s2);
    if (_CrtMemDifference(&s3, &s1, &s2))
        _CrtMemDumpStatistics(&s3);
    return 0;
}

The above code takes snapshot of the application memory before and after allocation of 4 bytes on heap. And since there is a memory leak between these 2 snapshots it will show up in the output window as follows: 4_ml.png

3. How to avoid memory leaks?

1. Every new, should be paired with a delete.

And every malloc(..)/calloc(..) with a free(..). Destroy any memory allocated on heap, in time.

int main() {
    int* p = new int(5);
    delete p;
    return 0;
}

2. If you are allocating any memory on heap in an object's constructor or member functions, destroy it in the object destructor.

Use free(..) in C and delete/delete[] in C++.

class object
{
  private:
    int* a;
  public: 
    object()
    {
       a = new int;
    }
    ~object()
    {
       delete a;
    }
};

3. Use virtual destructors.

Virtual destructors make sure the destructor of the inherited type is always executed and hence prevent memory leaks.

References

docs.microsoft.com/en-us/visualstudio/debug..