It happens quite too often that a C++ application allocates memory but doesn’t deallocate it. This is the job of the operator to new and delete. Thanks to them both, you can explicitly manage the memory management of an application.
Occasionally, I had to verify that a customer’s application correctly releases its memory. In particular, programs running for an extended period and often allocating and deallocating memory are challenging from the memory management perspective. Of course, the automatic memory release during the program’s shutdown is not an option.
As a baseline of my analysis, I use a simple program that often allocates and deallocates memory. In production, the code is bigger. That does not affect my strategy.
The key question is. Is there a corresponding delete for each new call?
The question is quite simple to answer by overloading the global operator new and delete. I count for each operator, how often it was called.
C++ offers the operator new in four variations.
The first two variations will throw a std::bad_alloc exception if they can not provide the memory. The last two variations return a null pointer. It’s quite convenient that is sufficient to overload only version 1 because versions 2 – 4 use the version 1: void* operator new(std::size_t count). This statement also holds for variants 2 and 4, designed for C arrays. You can read the details of the global operator new here: cppreference.com.
The statements also hold for operator delete.
C++ offers six variations for operator delete.
According to operator new, it is sufficient to overload for operator delete the first variant because the remaining five use void operator delete(void* ptr) as a fallback. Only a word about the two last versions of operator delete. You have in this version the length of the memory block in the variable sz to your disposal. Read the details here at cppreference.com.
This time I use the program overloadOperatorNewAndDelete.cpp the header myNew.hpp (line 3). The same holds for line 34. Here I invoke the function getInfo to get information about my memory management.
I create in the file two static variables alloc and dealloc (lines 10 and 11). They keep track of how often I used the overloaded operator new (line 13) and operator delete (line 18). I delegate in the functions the memory allocation to std::malloc and the memory deallocation to std::free. The function getInfo (lines 23 – 31) provides me with the numbers and displays them.
The question is. Have I cleaned everything clean?
Of course, not. That was the intention of this and the following post. Now I know that I have leaks. Maybe it helps to determine the addresses of the objects which I have forgotten to clean up.
Addresses of the memory leaks.
So, I have to put more cleverness into the header myNew2.hpp.
The key idea is to use the static array myAlloc (line 15) to keep track of the addresses of all std::malloc (line 19) and std::free (line 19) invocations. Of course, I can not use the function operator new container that needs dynamic memory. This container would invoke the operator new. A recursion that would cause my program to crash. Therefore, I use a std::array in line 15 because std::array gets its memory at compile time. Now it can happen that my std::array becomes too small. Therefore, I invoke myAlloc.at(counter++) to check the array boundaries.
Which memory address have I forgotten to release? The output answers.
A simple search for the object having the address is no good idea. Because it is quite probable that a new call of std::malloc reuses an already-used address. That is ok if the objects have been deleted in the meantime.
But why are the addresses part of the solution? I have only to compare the memory address of the created objects with those of the not deleted objects.
Comparison of the memory addresses
In addition to the memory address, I have the reserved memory size at my disposal. I use this information in operator new.
Now, the allocation and deallocation of the application are more transparent.
A simple comparison shows. I forget to release an object with 4 bytes and an object with 400 bytes. In addition, the allocation sequence in the source code corresponds to the sequence of outputs in the program. Now, it should be quite easy to identify the missing memory releases.
The program is not beautiful in two ways. First, I statically allocate the memory for std::array; second, I want to know which object was not released. In the next post, I will solve both issues.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, Marco Parri Empoli, moon, and Philipp Lenk.
Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.
|My special thanks to Embarcadero|
|My special thanks to PVS-Studio|
|My special thanks to Tipi.build|
|My special thanks to Take Up Code|
|My special thanks to SHAVEDYAKS|
I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
- Embedded Programmierung mit modernem C++ 12.12.2023 – 14.12.2023 (Präsenzschulung, Termingarantie)
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
- C++ – The Core Language
- C++ – The Standard Library
- C++ – Compact
- C++11 and C++14
- Concurrency with Modern C++
- Design Pattern and Architectural Pattern with C++
- Embedded Programming with Modern C++
- Generic Programming (Templates) with C++
- Clean Code with Modern C++
- Phone: +49 7472 917441
- Mobil:: +49 176 5506 5086
- Mail: schulung@ModernesCpp.de
- German Seminar Page: www.ModernesCpp.de
- Mentoring Page: www.ModernesCpp.org
Modernes C++ Mentoring,