Click here to Skip to main content
13,737,154 members
Click here to Skip to main content
Add your own
alternative version


66 bookmarked
Posted 16 Apr 2008
Licenced CPOL

Heap Memory Manager and Garbage Collector

Rate this:
Please Sign up or sign in to vote.
Descripes a module to track heap memory allocations and to avoid memory leaks.



This article demonstrates a method to try and solve a common problem hated by most C++ programmers: memory leaks and memory overruns. The method used in this article is to track all memory allocated by the program. It also has basic protection checks whether the memory written to the allocated block has overrun the number of bytes actually allocated.

This method also lets you organize and group allocated memory by ID or by name. Giving a name to a memory allocation gives the advantage that you can get the memory allocated by name while not needing to keep a pointer running around. Giving a group ID to an allocation helps the programmer to keep memory allocations grouped and thus can call a single function to deallocate all memory of a certain group.

Why Track Memory?

Tracking memory is a very efficient way to keep an eye on all allocated memory. This gives you the ability to later enumerate all memory blocks allocated and also to deallocate all memory allocated. This is a garbage collection implementation.

Why Garbage Collection?

Garbage collection is used very much in modern programming languages like all .NET languages and Java. Having a garbage collection implementation in C++ does not come without its price, but it is always a safe way to remove memory leaks completely.

The Problem

When allocating memory, it has to be deallocated at some point or another. It is very easy not to deallocate the memory, either by programming errors or by the program logic. Example:

void ServePizzas(int pizzacount)
    char* p = new char[pizzacount];

    // ... more code here...

    if (g_remainingpizzas == 0) return;

    // ... more code here...

    delete [] p;

In the code above, a memory block is allocated with the char* p = new char[pizzacount]; statement. The conditional statement in the middle has a return statement and causes the function to exit and all the code after it will not be executed. Since the delete [] p; statement will not be executed, the memory allocated will not be freed thus resulting in a memory leak.

Presented Solution

The solution presented in this article involves overriding the C++ new and delete operators. The new operator is normally called like this:

char* p = new char[256];

This allocates a 256 byte array in pointer p. When using this library, the call remains as-is, but internally, the memory has been marked and tracked, allowing control over the allocated memory.

The new operator can also have parameters, and in this library, the new operator has three overloads with parameters. Let's look at some examples:

// Allocate a 256 byte array using normal new operator.
char* p = new char[256];

// Allocate a 256 byte array with group ID 1.
char* p1 = new(1) char[256];

// Allocate a 256 byte array with name "my array"
char* p2 = new("my array") char[256];

// Allocate a 256 byte array with name "his array" with group ID 1.
char* p3 = new(1, "his array") char[256];

These were all the ways to allocate memory. To deallocate the memory allocated in the previous example, we normally do the following:

delete [] p;
delete [] p1;
delete [] p2;
delete [] p3;

Now, let's say that we lost the pointers p, p1, p2, and p3, how can we deallocate the memory? There are many ways with the memory tracker library. Let's find out how:

Method 1: Recover pointers

// We cannot recover p since it is not named.
char* p = Null;//???

// We cannot recover p1 since it is not named.
char* p1 = Null;//???

// Recover p2:
char* p2 = hmt_getnamed("my array");
delete [] p2;

// Recover p3:
char* p3 = hmt_getnamed("his array");
delete [] p3;

In this method, we could recover most of the pointers but could not recover pointer p and p1 since we did not assign a name to them. There is still a way to deallocate them though. Let's look at method 2:

Method 2: Deallocating groups

// Deallocate group 0; p and p2
// Deallocate group 1; p1 and p3

In this method, we deallocate group 1 since p1 and p3 were assigned to group 1, and group 0 since p and p2 were not assigned to any group and thus they belong to group 0. Let's have a look at a more brute-force approach:

Method 3: Deallocating all

// Deallocate all memory allocated by new.

In this method, we force all memory allocated by the new operator to be deallocated, even p which was allocated using the normal new operator. This makes sure that there are no memory leaks.

More Information

If you need to know how much memory the program has allocated, you can use the following code:

size_t memallocated = hmt_getallocated();
printf("Memory allocated using new: %d", memallocated);

If you need to print debug information on all the memory allocated:


If you want to print debug information to see if any memory block has been overrun or trashed:


Implementation Details

Since we override the new statement, we have control on how much memory is allocated. Some more memory than actually requested is allocated to make space for tracking data.

The overhead for each memory allocation is 32 bytes for 32-bit processors, and 64 bytes for 64-bit processors. The following table represents the internal memory structure of an allocated block when the new statement is called. This also indicates how the memory tracker knows about all the memory allocated.

Number of bytesFieldDescription
4 bytesTrash UIDUsed to determine if memory has been overwritten.
4 bytesGroup IDGroup ID of allocated block.
4 bytesHash of nameIf item is named, this will contain a hash of the name.
4 bytesFlagsInternal flags to describe memory block.
Pointer *SizeSize of block including overhead.
Pointer *Previous blockLinked list pointer to previous allocated block.
Pointer *Next blockLinked list pointer to next allocated block.
n bytesAllocated memory **Actual memory requested by the new statement.
4 bytesTrash UIDUsed to determine if memory has been overwritten.

* 4 bytes for 32-bit processor, 8 bytes for 64-bit processor.

** The pointer returned by the new statement points to this memory block.

With this structure, all memory blocks are known and linked together.


This module is part of a larger, more complex, memory pool module which should be published later on. There is, for sure, room for improvement in this module, one of them being the lookup of names, which is a linear search, and thus slow when there are a large number of memory allocations. In the memory pool module, a binary tree is used to speed up things, but that is for later.

This module is by no means the only method to do this kind of memory tracking, but it is a pretty efficient way to remove memory leaks.

Revision History

  • 16-04-2008: Original article.


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


About the Author

Andrei C_Coder Azzopardi
CEO GoldBolt Software
Malta Malta
Andrei is CEO of GoldBolt Software. He is a self taught developer were he first started writing programs and games using Basic and Z80 assembler on an Amstrad CPC back in 1985 at the age of 7. He specializes in the C++ language having used it for more than 20 years. As CEO of GoldBolt Software, he now develops using mostly .NET technologies for fast development but he still exercises in the use of C++ when writing optimized low level programs.

You may also be interested in...


Comments and Discussions

GeneralMy vote of 2 Pin
Dmitriy Ryajov5-Oct-11 7:46
memberDmitriy Ryajov5-Oct-11 7:46 
GeneralRe: My vote of 2 Pin
Andrei C_Coder Azzopardi7-May-12 21:35
memberAndrei C_Coder Azzopardi7-May-12 21:35 
GeneralSeriously flawed [modified] Pin
Bacon Ultimate Cheeseburger24-Jul-09 15:46
memberBacon Ultimate Cheeseburger24-Jul-09 15:46 
GeneralRe: Seriously flawed Pin
Andrei C_Coder Azzopardi24-Jul-09 22:12
memberAndrei C_Coder Azzopardi24-Jul-09 22:12 
GeneralRe: Seriously flawed Pin
Bacon Ultimate Cheeseburger25-Jul-09 13:43
memberBacon Ultimate Cheeseburger25-Jul-09 13:43 
GeneralRe: Seriously flawed Pin
Andrei C_Coder Azzopardi29-Jul-09 23:50
memberAndrei C_Coder Azzopardi29-Jul-09 23:50 
GeneralMy vote of 1 Pin
Achilleas Margaritis17-Feb-09 6:40
memberAchilleas Margaritis17-Feb-09 6:40 
GeneralVery useful Pin
DGyurka2-Jan-09 11:49
memberDGyurka2-Jan-09 11:49 
GeneralRe: Very useful Pin
Andrei C_Coder Azzopardi4-Jan-09 8:21
memberAndrei C_Coder Azzopardi4-Jan-09 8:21 
GeneralThat is no garbage collection Pin
Achilleas Margaritis4-Sep-08 6:31
memberAchilleas Margaritis4-Sep-08 6:31 
GeneralRe: That is no garbage collection Pin
Andrei C_Coder Azzopardi4-Sep-08 7:30
memberAndrei C_Coder Azzopardi4-Sep-08 7:30 
GeneralRe: That is no garbage collection Pin
Achilleas Margaritis5-Sep-08 1:04
memberAchilleas Margaritis5-Sep-08 1:04 
GeneralRe: That is no garbage collection Pin
Andrei C_Coder Azzopardi5-Sep-08 1:08
memberAndrei C_Coder Azzopardi5-Sep-08 1:08 
GeneralRe: That is no garbage collection Pin
Achilleas Margaritis5-Sep-08 1:11
memberAchilleas Margaritis5-Sep-08 1:11 
GeneralRe: That is no garbage collection Pin
Andrei C_Coder Azzopardi5-Sep-08 1:33
memberAndrei C_Coder Azzopardi5-Sep-08 1:33 
GeneralRe: That is no garbage collection Pin
Achilleas Margaritis17-Feb-09 6:38
memberAchilleas Margaritis17-Feb-09 6:38 
Generalstd::vector<char*> dict.push_back(); is also getting overridden ... Pin
ArtificialIntelligence1231-Jul-08 2:43
memberArtificialIntelligence1231-Jul-08 2:43 
GeneralRe: std::vector<char*> dict.push_back(); is also getting overridden ... Pin
JeanLuc_16-Jul-08 14:27
memberJeanLuc_16-Jul-08 14:27 
Questioncool ideals,but how to download the code? Pin
christanxw18-Jun-08 4:22
memberchristanxw18-Jun-08 4:22 
AnswerRe: cool ideals,but how to download the code? Pin
Andrei C_Coder Azzopardi18-Jun-08 4:55
memberAndrei C_Coder Azzopardi18-Jun-08 4:55 
GeneralNice article Pin
LeonardoTorres14-May-08 11:19
memberLeonardoTorres14-May-08 11:19 
GeneralRe: Nice article Pin
Andrei C_Coder Azzopardi14-May-08 12:50
memberAndrei C_Coder Azzopardi14-May-08 12:50 
GeneralSuggestion Pin
JTAnderson1-May-08 8:26
memberJTAnderson1-May-08 8:26 
GeneralHelp to find mis-match between new[] operator and delete operator Pin
Steve (axa) Miller29-Apr-08 2:31
memberSteve (axa) Miller29-Apr-08 2:31 
GeneralRe: Help to find mis-match between new[] operator and delete operator Pin
Andrei C_Coder Azzopardi29-Apr-08 2:45
memberAndrei C_Coder Azzopardi29-Apr-08 2:45 

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

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

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06-2016 | 2.8.180920.1 | Last Updated 16 Apr 2008
Article Copyright 2008 by Andrei C_Coder Azzopardi
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid