home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
mag&info
/
ptv3n5.zip
/
NEWDEBUG.CXX
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-29
|
5KB
|
201 lines
/////////////////////////////////////////////////
// DEBUG DYNAMIC MEMORY ALLOCATION
// newdebug.cxx
//
// Implements a debugging replacement for
// the standard C++ memory allocation
// operators.
//
// Tested with:
// Microsoft C/C++ 7.00
// Borland C++ 3.x
//
// Copyright 1992 Scott Robert Ladd
// All Rights Reserved
/////////////////////////////////////////////////
#include "newdebug.h"
#include "stdlib.h"
//-----------------------
// static initializations
//-----------------------
long NewDbg::Count = 0;
long NewDbg::Bytes = 0;
void (* NewDbg::ErrorFunc)(NewDbg::Errors flag)
= NULL;
NewDbg::Errors NewDbg::ErrorFlag
= EF_OKAY;
const unsigned short NewDbg::CorrectMark
= 0x1701;
//----------------------------
// NewDbg member functions
//----------------------------
int NewDbg::IsDynamic(void * ptr)
{
// get pointer to header data
AllocHeader * trueptr = (AllocHeader *)ptr;
--trueptr;
// return non-zero if marker is correct
return (trueptr->Marker == CorrectMark);
}
long NewDbg::GetCount()
{
return Count;
}
long NewDbg::GetBytes()
{
return Bytes;
}
NewDbg::Errors NewDbg::GetError()
{
return ErrorFlag;
}
void NewDbg::ClearError()
{
ErrorFlag = NewDbg::EF_OKAY;
}
void NewDbg::InstallHandler
(void (* func)(Errors flag))
{
ErrorFunc = func;
}
void NewDbg::ReportError(Errors err)
{
// set current error code
ErrorFlag = err;
// if a handler function is assigned, call it
if (ErrorFunc != NULL)
ErrorFunc(ErrorFlag);
}
//--------------------------------------
// new_handler, operators new and delete
//--------------------------------------
void (* _new_handler)() = NULL;
void (* set_new_handler(void (* handler)()))()
{
// save current pointer for return
void (* result)() = _new_handler;
// assign user function to _new_handler
_new_handler = handler;
return result;
}
void * operator new (size_t size)
{
// if there's an error, don't allocate
if (NewDbg::ErrorFlag != NewDbg::EF_OKAY)
return NULL;
// catch attempts to allocate zero bytes
if (size == 0u)
{
NewDbg::ReportError(NewDbg::EF_ZEROSIZE);
return NULL;
}
// calculate size of allocation plus header
size_t actualsize =
size + sizeof(NewDbg::AllocHeader);
// call malloc to allocate memory
NewDbg::AllocHeader * temp =
(NewDbg::AllocHeader *)malloc(actualsize);
// a NULL pointer indicates allocation failure
if (temp == NULL)
{
// report that allocation failed
NewDbg::ReportError(NewDbg::EF_NOTALLOC);
// call _new_handler if it isn't NULL
if (_new_handler != NULL)
_new_handler();
return NULL;
}
// set values in header
temp->Marker = NewDbg::CorrectMark;
temp->Bytes = size;
// increment tracking variables
++NewDbg::Count;
NewDbg::Bytes += size;
// set temp to actual data (past header)
temp++;
return temp;
}
void operator delete (void * ptr)
{
// if there's an error, don't allocate
if (NewDbg::ErrorFlag != NewDbg::EF_OKAY)
return;
// get pointer to beginning of data
NewDbg::AllocHeader * trueptr =
(NewDbg::AllocHeader *)ptr;
// back up to start of header
--trueptr;
// verify that this IS an allocated pointer
if (trueptr->Marker != NewDbg::CorrectMark)
NewDbg::ReportError(NewDbg::EF_INVALID);
else
{
// reverse the bit in the maker so this
// block cannot be deleted again
trueptr->Marker = ~NewDbg::CorrectMark;
// reduce total bytes allocated by size
// of this block
NewDbg::Bytes -= trueptr->Bytes;
// if the number of bytes allocated is
// less than 0, something went wrong
if (NewDbg::Bytes < 0)
NewDbg::ReportError(
NewDbg::EF_UNDERFLOW);
else
{
// if the count equals zero, too
// many deletions have occurred
if (NewDbg::Count == 0)
NewDbg::ReportError(
NewDbg::EF_TOOMANY);
else
{
// decrement number of allocations
--NewDbg::Count;
// free the pointer
free(trueptr);
}
}
}
}