18 #ifndef HEAP_CHECK_HPP 19 #define HEAP_CHECK_HPP 23 #define HC_ASSERT_ERROR _HC_DoAssert(__FILE__,__FUNCTION__,__LINE__) 24 #define HC_ASSERT(exp) if (!(exp)) {HC_ASSERT_ERROR;} else 25 #define HC_NOTES(ptr,notes) HeapCheck.UpdateNotes(ptr,notes) 27 #define HC_COMP_ASSERT(exp) extern char _HC_CompAssert[(exp)?1:-1] 30 #define HC_ABS(x) (((x)>0)?(x):-(x)) 31 #define HC_ISPOWER2(x) (!((x)&((x)-1))) 32 #define HC_ALIGNMENT (sizeof(int)) 33 #define HC_DOALIGN(num) (((num)+HC_ALIGNMENT-1)&~(HC_ALIGNMENT-1)) 37 #define USE_HC_ASSERT \ 38 extern "C" void HC_ReportAssert ( const char*, const char*, long ); \ 39 static int _HC_DoAssert ( const char* file, const char* func, int nLine ) \ 41 HC_ReportAssert(file, func, nLine); \ 104 flag_blocks_checked =
false;
133 for(
int i = 0; i < (int)m_mem_blocks.size(); i++ )
135 if( m_mem_blocks[i] != NULL )
138 m_mem_blocks[i] = NULL;
143 m_mem_blocks.clear();
145 #if defined(MATLAB_MEX_FILE) 146 if( !count && !flag_blocks_checked )
148 PRINTF(
"Heap check: ok\n" );
151 flag_blocks_checked =
true;
172 return ( (ptr) && (!( (
long)ptr & (
HC_ALIGNMENT-1) )) );
209 m_mem_blocks.push_back( ptr );
210 flag_blocks_checked =
false;
218 for(
int i = 0; i < (int)m_mem_blocks.size(); i++ )
220 if( m_mem_blocks[i] == ptr )
222 m_mem_blocks.erase( m_mem_blocks.begin() + i );
239 void*
New(
size_t bytes,
const char* file,
const char* fcn,
const char* notes,
long nLine )
247 if( mem_block != NULL )
251 mem_block->
lpMem = mem_block + 1;
257 memset( mem_block->
lpMem, 0, bytes_aligned );
267 return mem_block ? (mem_block + 1) : NULL;
283 const char* file,
const char* fcn,
const char* notes,
long nLine )
285 void* ptr_new = NULL;
303 header_ins = header_new ? header_new : header;
306 header_ins->
lpMem = header_ins + 1;
316 ptr_new = header_new ? (header_new + 1) : NULL;
328 ptr_new =
New( bytes_aligned, file, fcn, notes, nLine );
342 size_t bytes_aligned = (
char*)(header->
lpFooter+1) - (
char*)header;
373 memset( lpBuffer, 0, szBuffer );
376 if( header->
lpMem == &header[1] )
378 _snprintf( lpBuffer, szBuffer,
"%08lx ", (
long unsigned)header );
380 if( header->lpFilename && (left = (
int)szBuffer - (
int)strlen(lpBuffer)) > 1 )
382 _snprintf( lpBuffer + strlen(lpBuffer), left,
"%12s %4ld ",
383 header->lpFilename, header->lLineNumber );
385 if( header->lpFunctionName && (left = (
int)szBuffer - (
int)strlen(lpBuffer)) > 1 )
387 _snprintf( lpBuffer + strlen(lpBuffer), left,
" (%s)",
388 header->lpFunctionName );
390 if( header->lpNotes && (left = (
int)szBuffer - (
int)strlen(lpBuffer)) > 1 )
392 _snprintf( lpBuffer + strlen(lpBuffer), left,
" %s",
396 _snprintf( lpBuffer, szBuffer,
"(bad)" );
407 void Walk(
const char* text = NULL )
409 for(
int i = 0; i < (int)m_mem_blocks.size(); i++ )
415 #if defined(MATLAB_MEX_FILE) 420 PRINTF(
"walk(%s): %s\n", text, buffer );
422 PRINTF(
"walk: %s\n", buffer );
431 #if defined( MAIN_MODULE ) 445 _snprintf( buffer, 1024,
"Assertion failed in %s, %s line %ld\n", file, lpFunctionName, line );
447 #if defined(MATLAB_MEX_FILE) 448 mxAssert( 0, buffer );
468 #endif // HEAP_CHECK_HPP void Free(void *ptr)
Freeing space returned from New() or Realloc()
#define HC_DOALIGN(num)
memory alignment
void * New(size_t bytes, const char *file, const char *fcn, const char *notes, long nLine)
Allocates a new block of memory with initialized header and footer.
void Release()
Releasing unfreed memory.
static int VerifyPtr(const void *ptr)
Checks if header pointer ptr is valid.
static int isPtrAligned(const void *ptr)
Checks if header pointer ptr is well aligned.
tagFooter * lpFooter
pointer to footer, contiguous to memory block
void HC_ReportAssert(const char *file, const char *lpFunctionName, long line)
Standard assert routine used by macro HC_ASSERT.
const char * lpFilename
filename or NULL
static size_t GetHeaderSize()
Returns the header size in bytes.
static void RenderDesc(const tagHeader *header, char *lpBuffer, size_t szBuffer)
Formatted output of memory block information (from its header)
#define HC_ALIGNMENT
align to integer
void AddPtr(const tagHeader *ptr)
Enqueues new memory block by header pointer ptr.
bool flag_blocks_checked
Flag will be set, when the block m_mem_blocks is released and checked.
void * lpMem
pointer to memory block (contiguous to this header space)
#define MEM_FREE(ptr)
standard memory free function
std::vector< const tagHeader * > vec_tagHeader
Memory blocks linked list typedef.
void RemovePtr(const tagHeader *ptr)
Removes memory block, identified by ptr without freeing it.
#define MEM_REALLOC(ptr, size)
standard memory deallocator
void * Realloc(void *ptr_old, size_t bytes, const char *file, const char *fcn, const char *notes, long nLine)
Reallocates a block of memory allocated with New()
long lLineNumber
line number or 0
const char * lpNotes
pointer to further notes or NULL
#define USE_HC_ASSERT
Macro USE_HC_ASSERT must exist in every module which uses macro HC_ASSERT.
tagHeader * lpHeader
pointer to header of this memory block
Helperclass for memory leak and access violation detection.
void Walk(const char *text=NULL)
Reporting walk through the linked memory list.
#define HC_ISPOWER2(x)
check if is a power of 2
HeapCheck()
Standard ctor.
vec_tagHeader m_mem_blocks
Linked list of memory blocks used in module scope.
const char * lpFunctionName
function name
#define HC_COMP_ASSERT(exp)
Verifies design-time assumptions (exp) at compile-time.
#define PRINTF
Global text output function.
void UpdateNotes(void *ptr, const char *notes)
Update "notes" field in memory block header.