Leaker – A simple C/C++ memory leak detector

Motivation

Memory errors are a constant thorn in the side of C and C++ programmers.  Unlike newer languages like Java and C#, C and C++ don’t automagically manage your memory for you.  Rather, you are in charge of explicitly allocating memory when you need it, and deallocating it once you’re finished.  It is particularly challenging for new C and C++ programmers, who are often still getting comfortable with the mechanics of pointers.

When I was tutoring C and C++ students at De Anza College, I encountered certain kinds of errors many times.  After discussing with instructors and other tutors, it seemed that a simple, general leak detection/reporting mechanism would be useful.

What is it?

Leaker is a simple memory leak detector for C/C++.  It tracks where and how you allocate and deallocate your memory.  Memory not deallocated at the end of execution is reported.  In addition, Leaker tries to detect and report other errors, such as deallocating pointers that have not been already allocated, writing off the end of arrays, and using incompatible allocators and deallocators.

Leaker is written in ANSI C++ and should work with any compliant C or C++ program and any standard compiler (tested with GCC, MS Visual C++, Clang and Intel C++).  It is designed for simplicity, speed and portability.

The basic strategy behind Leaker is to record all memory allocations and where they occurred in a lookup table.  When a deallocation function is called, the table is checked, and an error can be reported if something incorrect is done.  At the end of execution, all remaining entries in the table are reported.  These ideas are discussed in more detail with the original proof-of-concept version.  See this post for more details on the current implementation.

Download

Version 0.1 (2011-10-15) – leaker-0.1.tgz

How to use it?

Leaker consists of two files – leaker.h and leaker.cpp.  To use, copy both to the directory with the rest of your code.  At the top of each .c or .cpp file in your program, include the leaker.h header file.  Then add the leaker.cpp file to your project and build.  When you run your program, errors will be report to standard error (stderr) prefixed with the string “LEAKER”.  When your program exits, a listing of all leaked allocations will be displayed.

If there are no errors or leaks, Leaker will not print any output.

Note that if the program you’re building is C only (not C++), you can rename leaker.cpp to leaker.c.

An example

Suppose you have written a program consisting of 2 files.

file1.cpp:

#include <stdlib.h>

char *printHello(void);


int main(int argc, char *argv[])

{

char *s;

s = printHello();

free(s);

return 0;

}

file2.cpp:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

char *printHello(void)

{

constchar *s = “Hello world!\n”;

char *str = new char[strlen(s)];

strcpy(str, s);

puts(s);

delete s;

return str;

}

To use Leaker, simple copy leaker.cpp and leaker.h to the directory, add #include “leaker.h” to the top of each file, and if you’re compiling with g++, instead of g++ file1.cpp file2.cpp -o program, use g++ file1.cpp file2.cpp leaker.cpp -o program.

In other words:

$ g++ file1.cpp file2.cpp leaker.cpp -o program
$ ./program

For your output you will see:

$ ./program
Hello world!

LEAKER: file2.cpp:printHello():12 delete error: pointer was not allocated!

LEAKER: file1.cpp:main():10 checking error: wrote off end of memory allocated at file2.cpp:printHello():9.

LEAKER: file1.cpp:main():10 mismatch error: memory allocated at file2.cpp:printHello():9 with new[], deallocated with free.

LEAKER: errors found!
Mismatches: 1 allocation/deallocations don’t match.
Overflows: 1 allocations overflowed (wrote off end).
Bad deallocs: 1 attempts made to deallocate unallocated pointers.

$

License

Leaker is provided as free software under the terms of the GNU GPL version 2.  There is no warranty.

Feedback

Feedback or error reports can be sent to me at zdhazeghi@zgmail.com.  Remove the ‘z’s before hitting send.