libcwd: The C++ Debugging Support Library - Reference Manual
Author: Carlo Wood
Description: C++ debugging support library with ostream debug output
Keywords: libcwd, debug output, debug facility, debug channel, object orientation, OO, C++, nested debug output, ostream, memory allocation, debugging, source file and line number

Main Page Reference Manual Namespace List Compound List Namespace Members Compound Members File Members

# Memory Allocation Markers: Memory Leak Checking
[Memory Allocation Debug Support]

Collaboration diagram for Memory Allocation Markers: Memory Leak Checking:

## Classes
class | libcwd::marker_ct
| A memory allocation marker. More...

## Detailed Description

Libcwd does a weak attempt to support debugging of memory leaks. I hope to greatly improve this in the future.

It is possible to mark allocations that are done till that moment, and then later check for memory leaks by expecting no other memory allocations than those that already existed before the mark. This is done by creating a marker_ct object. The check for memory leaks is done when the marker is removed again. This can be done recursively.

A marker is created by passing it a description:

    #if CWDEBUG_MARKER
      libcwd::marker_ct* marker = new libcwd::marker_ct("Description of the marker");
    #endif

Any allocation done after the creation of this marker will be reported as a leak at the moment the marker is deleted.

Markers are clearly visible in the Allocated memory Overview. They are labeled MARKER (see also the allocator type table). All memory that is allocated after a marker, is displayed indented and below that marker in the Allocated memory Overview.

Finally, it is possible to move specific memory blocks outside markers, so they will not cause a memory leak detection. This is done with the function

    namespace libcwd {
      void move_outside(marker_ct* marker, void const* ptr);
    }

which would move the memory allocation pointed to by ptr outside the test region of marker.

A complete example program with output is given here:

    #ifndef _GNU_SOURCE
    #define _GNU_SOURCE
    #endif
    #include <libcwd/sys.h>
    #include <libcwd/debug.h>

    // A dummy class
    class A {
      int i;
      int j;
      char k;
    };

    int main(int argc, char* argv[])
    {
      // Don't show allocations that are allocated before main()
      Debug( make_all_allocations_invisible_except(NULL) );

      // Select channels
      ForAllDebugChannels( if (debugChannel.is_on()) debugChannel.off() );
      Debug( dc::notice.on() );
      Debug( dc::malloc.on() );
      Debug( dc::warning.on() );
      // Debug( dc::bfd.on() );

      // Write debug output to cout
      Debug( libcw_do.set_ostream(&cout) );

      // Turn debug object on
      Debug( libcw_do.on() );

      // Allocate new object
      A* a1 = new A;
      AllocTag(a1, "First created");

    #if CWDEBUG_MARKER
      // Create marker
      libcwd::marker_ct* marker = new libcwd::marker_ct("A test marker");
    #endif

      // Allocate more objects
      A* a2 = new A[10];
      AllocTag(a2, "Created after the marker");
      int* p = new int[30];
      AllocTag(p, "Created after the marker");

      // Show Memory Allocation Overview
      Debug( list_allocations_on(libcw_do) );

      Dout(dc::notice, "Moving the int array outside of the marker...");
    #if CWDEBUG_MARKER
      Debug( move_outside(marker, p) );
    #endif

      // Show Memory Allocation Overview
      Debug( list_allocations_on(libcw_do) );

    #if CWDEBUG_MARKER
      // Delete the marker
      delete marker;
    #endif

    #if CWDEBUG_ALLOC
      Dout(dc::notice, "Finished successfully.");
    #else
      DoutFatal(dc::fatal, "Please reconfigure libcwd with --enable-alloc.");
    #endif
      return 0;
    }