// -*-c++-*-
//
// RCS data:
// $Date: 2003/06/23 14:47:24 $
// $Revision: 1.1.1.1 $
// $Source: /cvsroot/miwm/miwm/miwm/mlchckr.h,v $
// $Id: mlchckr.h,v 1.1.1.1 2003/06/23 14:47:24 bwise837 Exp $
// $RCSfile: mlchckr.h,v $
//
// ------------------------------------------
// Copyright by Ben Paul Wise.
// -------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ------------------------------------------
//         start of  mlchckr.h  
// ------------------------------------------
// this checks for memory leaks and double-deletes
// in your C++ code. It does this by overloading
// new, new[], delete and delete[].
//
// ------------------------------------------
//
// As this uses a linear scan of unordered memory in
// GetHoldBlock, it takes quadratic time to clear memory.
// This can change total-application-cleanup time from
// an eye-blink to 30-45 seconds. So shut it off on releases.
// Note that it does perform the simple optimization of putting
// fresh blocks of memory at the front, so that rapid
// new/delete cycles will only scan the start of the list.
//
// ------------------------------------------
//
// Notice what this does NOT do:
//
// (A) check C (or C-ish) code.
//      It uses malloc and free, not new and delete.
//
// (B.1) check for external resource wastage.
//      For example, causing the X server to allocate more
//      and more items pixmaps, without
//      ever XtFree-ing them. It's not in *your* code.
// (B.2) this can be subtle: in my window manager MIWM,
//      the list of clients is a structure created by 'new'
//      in C++, but the items are client structures created
//      by X using malloc in C.
//
// (C) check for memory corruption.
//      use Electric Fence for that.
//
// ------------------------------------------
//
// you don't need to change your class-definition or -implementation
// code at all, and you use regular " foo = new Bar(stuff); "
//
// ------------------------------------------
// 
// the verbosity is variable: 
// level 0: do nothing
// level 1: track allocations and report the amount leaked
// level 2: level 1, and report each individual memory leak
// level 3: level 2, and report each allocation/deallocation as it occurs
//
// If you switch verbosity between 0 and non-zero during a checking
// session, you will almost certainly get it massively confused.
// ------------------------------------------


#ifndef MEMORYCHECKER
#define MEMORYCHECKER

using namespace std;

#include <iostream>
#include <list>
#include <stack>

using std::list;
using std::stack;

// set this is YOUR code, not in the library
extern unsigned int FirstSuspectBlock;


// ------------------------------------------

class MemoryHolderBlock
{
 public:
	
  MemoryHolderBlock ();
  MemoryHolderBlock (unsigned int BlockID,  unsigned int stAllocateBlock,void * NewMemory);

  ~MemoryHolderBlock (){}

	
// private:
  unsigned int BID;
  unsigned int BSize;
  void * BPointer;
	
};


// new operator overload.
extern void *operator new( size_t stAllocateBlock) throw (std::bad_alloc);
extern void *operator new[]( size_t stAllocateBlock) throw (std::bad_alloc);

// delete operator overload.
extern void operator delete( void *pvMem) throw();
extern void operator delete[]( void *pvMem) throw();


// you can start and stop before and after well-defined sections
// of code, in order to check just that.
extern void StartMemoryLeakCheck(unsigned int level);
extern void StopMemoryLeakCheck();
extern void AbortMemoryLeakCheck();

// ------------------------------------------

#endif

// ------------------------------------------
//          end of mlchckr.h
// ------------------------------------------
