How to Find Memory Leaks in C++

Saad Aslam Feb 16, 2024
  1. Memory Leaks in C++
  2. Handle Memory Leaks in C++
  3. Ways to Avoid Memory Leaks in C++
  4. Use Valgrind to Find Memory Leaks in C++
  5. Use CRT Library to Find Memory Leaks in C++
How to Find Memory Leaks in C++

This article will explain memory leaks, their causes, how to identify them, and how to prevent them using the C++ programming language.

Memory Leaks in C++

Memory is said to be “leaked” if the part of memory that the programmer has previously assigned to one purpose is utilized for another. When something like this happens, the programmer does not correctly deallocate the resource.

At this point, the program does not need the use of such RAM. As a result, there is no reason to maintain the reservation for that seat.

Memory leaking happens in C++ when programmers allocate memory by using the new keyword but fail to deallocate the memory by using the delete() function or the delete[] operator; this results in memory being lost. Memory leakage is caused by the incorrect delete operator most of the time.

The delete[] operator may release data in an array.

If we change the oil in our automobile but neglect to replace a seal or tighten a screw simultaneously, we are likely to run into significant problems when driving.

The engine of our automobile will eventually seize up since all of the oil will eventually flow out of the car; C++ programming will lead to precisely the same outcome.

When a programmer allocates memory dynamically but does not afterward free up that memory, a memory leak results, and memory allocation can be done as follows.

int *data;
data = (int *)malloc(8);
char *login = new char(40);

When we dynamically allocate memory, that memory comes from the heap, which is a portion of the system memory that C++ utilizes. The stack is where variables and functions are taken from.

There will be a memory leak if we don’t add the following code to clear up these allocations. These leaks would build up over time and, depending on our program logic, may cause our application to fail.

free(data);
delete login;

Here’s another case where a function is being created to allocate eight bytes of heap space for a pointer. This will take up 8 bytes on a 64-bit computer.

Those bytes will not be freed after the program completes execution.

#include <iostream>
using namespace std;

void data_leak() { double *pointer = new double(28.54); }
int main() { data_leak(); }

Adding the following loop code in the above code block will cause a million bytes to be allocated but never freed. We should probably save any open files before executing this code.

Even the most cutting-edge operating systems would have no trouble with this, but if we were to add any additional instruction to the for loop, we might run into trouble. This is why memory leaks can be so dangerous.

for (int j = 0; j < 150000; j++) {
  data_leak();
}

Handle Memory Leaks in C++

First, we make a function named func_to_handle_memory_leak(), then we declare an integer type pointer to handle a memory leak, then assign an integer value with the keyword new int().

void func_to_handle_memory_leak() { int* ptr = new int(6); }

Now we use the delete() function to clear previous memory and avoid memory leaks in the program. All activities will be carried out as soon as the function is called, and allocated memory will be freed before the function returns.

delete (ptr);

In the main function, we call our func_to_handle_memory_leak() function.

int main() {
  func_to_handle_memory_leak();
  return 0;
}

Complete source code:

#include <iostream>
using namespace std;

void func_to_handle_memory_leak() {
  int* ptr = new int(6);
  delete (ptr);
}
int main() {
  func_to_handle_memory_leak();
  return 0;
}

Ways to Avoid Memory Leaks in C++

  1. Instead of manually managing the memory, you should make an effort to utilize smart pointers whenever possible.
  2. Instead of char\*, you should use std::string. The std::string class is lightning fast and highly optimized; it takes care of all memory management internally.
  3. The best way to avoid memory leaks in C++ is to have a few new and delete calls at the program level. Anything that requires dynamic memory should be buried inside an RAII object that releases the memory when it goes out of scope; RAII allocates memory in the constructor and releases it in the destructor so that memory is guaranteed to be deallocated when the variable leaves the current scope.
  4. Memory should be allocated using the new keyword, and memory should be deallocated using the delete keyword, with all code being written between these two instructions.

Use Valgrind to Find Memory Leaks in C++

A memory leak is one of the most insidious kinds of programming error since it doesn’t manifest as a noticeable issue until you’ve exhausted your system’s memory and a call to malloc fails.

In fact, without garbage collection, about half of your effort may be spent ensuring that memory is properly freed when dealing with languages like C or C++.

To see the current list of supported tools, just run Valgrind, then choose the one you wish to use when executing your code.

Running Valgrind with the memcheck tool will enable us to check accurate memory consumption; it will provide a summary of every free and malloc call.

To explain, we’ll use a basic program called memoryleakdemo.

#include <stdlib.h>

int main() {
  char *x = new char[100];
  return 0;
}

This will display some information about the program, including a list of malloc calls without corresponding free calls.

% valgrind --tool=memcheck --leak-check=yes memoryleakdemo

We know that a call to malloc in main was responsible for the memory leak, but we cannot locate the specific line number. The issue is that we did not build the program using GCC’s -g option, which provides debugging symbols.

The following output is what we get if we recompile the program using debugging symbols.

==2022== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2022==    at 0x1B900DD0: malloc (vg_replace_malloc.c:131)
==2022==    by 0x804840F: main (memoryleakdemo.c:5)

Use CRT Library to Find Memory Leaks in C++

Memory leaks may be located and identified using the Visual Studio debugger and the C Run-Time (CRT) libraries.

Activate Memory Leak Detection

You must include the following statements in your application to activate the debug heap functions.

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>

After you have used these commands to activate the debug heap functions, you may insert a call to _CrtDumpMemoryLeaks before an application exit point so that a memory-leak report is shown when your program terminates.

_CrtDumpMemoryLeaks();

The memory leak report is sent to the Debug tab of the Output window when _CrtDumpMemoryLeaks is run. This is the default behavior.

You may use the _CrtSetReportMode function to send the report to a different place.

The output of the CRT Library Memory Leak:

The _CrtDumpMemoryLeaks will produce a memory-leak report similar to the one shown below if your application does not declare _CRTDBG MAP ALLOC.

Detected memory leaks!
Dumping objects ->
{18} normal block at 0x00780E80, 64 bytes long.
 Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

The memory-leak report will look like this if your application specifies _CRTDBG MAP ALLOC.

Detected memory leaks!
Dumping objects ->
c:\users\username\documents\projects\leaktest\leaktest.cpp(20) : {18}
 normal block at 0x00780E80, 64 bytes long.
 Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
Author: Saad Aslam
Saad Aslam avatar Saad Aslam avatar

I'm a Flutter application developer with 1 year of professional experience in the field. I've created applications for both, android and iOS using AWS and Firebase, as the backend. I've written articles relating to the theoretical and problem-solving aspects of C, C++, and C#. I'm currently enrolled in an undergraduate program for Information Technology.

LinkedIn

Related Article - C++ Memory