TMalloc Library

A short overview of the TMalloc library contained in jlib.lib - created by John Findlay

library version 1.01

When allocating and freeing many memory blocks especially in a large programmes it is sometimes difficult to find and eradicate any unfree-ed allocated memory - this is commonly called 'memory leaks'. TMalloc eases this task by keeping a record of all allocated memory, storing the size, type, translation unit and line number of each memory allocation and reporting any un-free-ed blocks when calling report_heap().

By including "tmalloc.h" in your listing the normal run time library's malloc(), realloc(), calloc() and free() are replaced by with tmalloc(), trealloc(), tcalloc() and tfree(). Using the macros provided in tmalloc.h, the same syntax as the original functions allows a seamless transition between using TMalloc functions and returning to the use of the run time library's functions.

When satisfied that all memory is being free-ed correctly, remove the tmalloc.h include and the normal malloc(), calloc(), realloc() and free() will be back in place.

The macros are defined in tmalloc.h -

#define malloc(n)        tmalloc( n, __FILE__, __LINE__ )
#define calloc(m,n)      tcalloc( m, n, __FILE__, __LINE__ )
#define free(n)          tfree( n, __FILE__, __LINE__ )
#define realloc(n, size) trealloc( n, size, __FILE__, __LINE__ )

The pre-processor directives '__FILE__' and '__LINE__' are included in each of the above macros so that the tmalloc library can store this information that is used to keep track of memory allocation and freeing.

Call report_heap() whenever you need to know what allocations have not been free-ed.

The prototype for report_heap()

void report_heap( char * pOutFile = NULL );

The prototype includes an optional parameter pOutFile. Calling report-heap() including a file name with cause the report to be written to disk, calling without passing a parameter will cause report_heap() to print to 'stdout'.

Example usage.

// test_tmalloc.c
#include <stdlib.h>  // for malloc and friends when not using "tmalloc.h"
#include "tmalloc.h" // tmalloc should be included after stdlib.h

int main( void )
{
    char * a = malloc( 1000 );
    char * b = calloc( 1, 2000 );
    char * c = malloc( 1000 );

#ifdef _TMALLOC_
    report_heap();
#endif

    b = realloc( b, 3000 );

#ifdef _TMALLOC_
    report_heap();
#endif

    free( a );
    free( b );
    free( c );

#ifdef _TMALLOC_
    report_heap("HeapReport.txt");
#endif

return 0;
}

_TMALLOC_ is defined in tmalloc.h and can be used as a pre-processor directive as shown in the above example. The calls for malloc(), realloc(), calloc() and free() can be left in place after removing the tmalloc header.

The following is an example of output from report_heap() either in a console window or as a file.

Walking though allocated heap

MEM:[00510B9C] TYPE:[MALLOC] FILE:[test_tmalloc.c] SIZE:[1000] LINE:[23]
MEM:[004100B0] TYPE:[CALLOC] FILE:[test_tmalloc.c] SIZE:[2000] LINE:[22]
MEM:[00510778] TYPE:[MALLOC] FILE:[test_tmalloc.c] SIZE:[1000] LINE:[21]

When there are no un-free-ed memory blocks report_heap() shows the following.

Walking though allocated heap

No heap to walk

If realloc is used in its malloc mode, i.e. realloc(NULL, size), repot_heap() will report an un-free-ed block as a MALLOC type not a REALLOC type.

Checks are carried out when calling the library's free() and realloc() that the pointer passed by the calling programme is valid - if it is not a valid pointer a MessageBox will be displayed stating this fact and the operation, either free() or realloc() will be aborted, control then returns to the calling programme.