Dereferee is a C++ template library intended for introductory C++ students learning about manual memory management and pointers. It provides a pointer template class that is instrumented to give highly detailed diagnostics about memory leaks, pointer-related errors that would normally cause a program crash, and other unwise behavior that may not cause an immediate failure but lead to one further down the line.

Unlike other pointer templates, such as std::auto_ptr and Boost's wide array of pointer templates, Dereferee's checked pointer does not to any memory management of its own--it will not fix problems, but merely report them so that the student can fix them on his or her own.

A journal paper describing Dereferee is currently in progress. This poster (TODO: Update link to permanent location) describing the toolkit was presented during a poster session at SIGCSE 2008.

Features

Dereferee detects and logs the following kinds of errors or other poor programming practices:

Dereferee can also optionally pad the ends of allocated memory blocks with "safety bytes" that are checked upon deletion to determine if bad pointer usage has caused any buffer underflows/overflows.

By default, the Dereferee memory manager will output at the end of execution a block of summary test that includes the size and location of any leaked memory blocks, as well as statistics about the number of calls made to new/delete and the amounts of memory used during execution.

Download

The Dereferee toolkit can be downloaded here from our SourceForgeProject.

This ZIP file contains the Dereferee source code, makefiles to support building a link library on a variety of platforms, a small demo application, and a comprehensive set of unit tests to ensure the consistency of Dereferee's diagnostics.

Requirements

Dereferee requires a C++ compiler with a very high level of standards-compliance, due to significant use of features like partial template specializations. Dereferee is currently known to work under the following compilers and platforms:

Furthermore, to support determining the source file location of errors that occur at runtime, Dereferee requires that it be possible to collect a backtrace at runtime and examine the symbol table of an executable. Pre-written modules have been written to support the following platforms:

When building the Dereferee library (see below), choose the appropriate listener module for your platform.

New platforms can be supported by writing a listener module that provides the appropriate lower-level functionality for that platform. New listeners can also be written to customize the manner by which Dereferee outputs its diagnostic messages.

A future version of Dereferee is likely to refactor these listeners into two separate components--one to handle the low-level aspects such as symbol table access and backtrace collection, and another to manage the output of the diagnostic messages.

Building Dereferee

You can use Dereferee either by including its source tree directly in the build process of your project, or separately compile it into a static library that can be linked into your project.

The Dereferee kit contains GNU makefiles for Cygwin, Mac OS X, and Unix platforms, and nmake makefiles for Visual C++. The makefile targets are as follows:

The value of the LISTENER variable described above is the name of the listener module object file, without a path or extension.

You can also use the run-tests and run-demo targets to automatically run the respective executable after it has been built.

For example, to build libdereferee.a on Mac OS X, you can run

    make libs LISTENER=gcc_macosx_listener

This will generate libdereferee.a in the Dereferee/build directory. For Microsoft Visual C++, you can run

    nmake /F Makefile.mak libs LISTENER=msvc_win32_listener

This will generate Dereferee.lib in the Dereferee/build-msvc directory. This library is compiled with the /MDd option to use the multithreaded debug DLL version of the Visual C++ C runtime library.

Usage

To use Dereferee in your own code, you must first prepare your project:

  1. Place the Dereferee/include directory in your project's include path.

  2. Include <dereferee.h> in any source or header file that will declare or use checked pointers.

  3. Link to the Dereferee static library (or include the source code for the library in your build process). Likewise, if you have not already linked a listener module object file into the static library itself, link to it as well.
  4. Use checked(T*) in lieu of T* when declaring pointers to heap memory in your code. This applies to variables, function arguments, and structure or class fields.

Notes:

The main design goal of the Dereferee toolkit is transparency; since this code was designed to be used by students who are just learning C++, it was highly desirable to make the functionality as unobtrusive as possible. Through C++ templates, operator overloading, and a minimal set of preprocessor macros, the Dereferee kit provides the checked(T*) syntax that can be used almost anywhere that a standard C++ heap pointer could be used. Only the declaration of the pointer need change; almost any other usage of the pointer (including calls to new/delete) will work as expected without modification.