From: Mike D. Lowis Date: Sun, 2 Oct 2011 04:41:46 +0000 (-0400) Subject: Initial commit X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=10dcf65a3a631d9cf8e1a8987720254d1f92b641;p=archive%2Fcork.git Initial commit --- 10dcf65a3a631d9cf8e1a8987720254d1f92b641 diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..15a01b7 --- /dev/null +++ b/README.txt @@ -0,0 +1,6 @@ +Overview +------------------------------------------------------------------------------- +Cork is a compiled in memory leak detector for C++. It provides overloaded new +and delete operators that track when and where objects are allocated and +deallocated. + diff --git a/src/cork.cpp b/src/cork.cpp new file mode 100644 index 0000000..5fb3e09 --- /dev/null +++ b/src/cork.cpp @@ -0,0 +1,183 @@ +#include "cork.h" + +#ifdef DETECT_MEM_LEAKS + +// We want to use the real malloc and free in this file +#undef malloc +#undef free + +#include +#include // for std::bad_alloc +#include // for malloc() and free() +#include + +// Set the namespace +using namespace std; +/****************************************************************************** + * Typedefs + *****************************************************************************/ +typedef struct BlockTableEntry +{ + void * ptr; + unsigned int size; + const char* file; + int line; + void * next; +} BlockTableEntry_T; + +typedef struct BlockTable +{ + unsigned int size; + BlockTableEntry_T* blocks[TBL_SIZE]; +} BlockTable_T; + +/****************************************************************************** + * Prototypes + *****************************************************************************/ +void insert_record(void * ptr, BlockTable_T* entry); +void erase_record(void * ptr); + +/****************************************************************************** + * Globals + *****************************************************************************/ +unsigned int allocated; +static BlockTable_T Block_Table = { 0, {0} }; + +/****************************************************************************** + * Function Definitions + *****************************************************************************/ +void insert_record(void * ptr, BlockTableEntry_T* entry) +{ + unsigned int index = ((unsigned int)ptr) % TBL_SIZE; + BlockTableEntry_T* last = Block_Table.blocks[ index ]; + BlockTableEntry_T* curr = last; + + while (curr != NULL) + { + if ( curr->ptr == ptr ) + { + curr->size = entry->size; + free(entry); + break; + } + last = curr; + curr = (BlockTableEntry_T*)curr->next; + } + + if(curr == NULL) + { + if (last != NULL) + { + last->next = entry; + } + else + { + Block_Table.blocks[index] = entry; + } + Block_Table.size++; + } +} + +void erase_record(void * ptr) +{ + int depth = 0; + unsigned int index = ((unsigned int)ptr) % TBL_SIZE; + BlockTableEntry_T* last = Block_Table.blocks[ index ]; + BlockTableEntry_T* curr = last; + + while( curr != NULL ) + { + depth = 1; + if( curr->ptr == ptr ) + { + depth = 2; + if(last == curr) + { + depth = 3; + Block_Table.blocks[ index ] = (BlockTableEntry_T*)curr->next; + } + else + { + depth = 4; + last->next = curr->next; + } + free(curr); + Block_Table.size--; + break; + } + last = curr; + curr = (BlockTableEntry_T*)curr->next; + } +} + +void Cork_ReportMemoryLeaks(void) +{ + unsigned int index = 0; + cout << "-----------------------------------------------------------------" << endl; + cout << "Cork: Memory Allocation Analysis" << endl; + cout << "-----------------------------------------------------------------" << endl; + cout << "You have " << Block_Table.size << " Unclaimed objects." << endl; + + for(; index < TBL_SIZE; index++) + { + BlockTableEntry_T* entry = Block_Table.blocks[ index ]; + while(entry != NULL) + { + cout << "\t" << entry->size << "\t" << entry->ptr; + if( entry->file != NULL ) + { + cout << "\t" << entry->line << "\t" << entry->file; + } + cout << endl; + entry = (BlockTableEntry_T*)entry->next; + } + } +} + +void * operator new (size_t size, string file, unsigned int line) +{ + void * ptr = malloc(size); + char * fname = (char*)malloc(file.length()); + if(ptr == NULL) + { + throw bad_alloc(); + } + else + { + BlockTableEntry_T* entry = (BlockTableEntry_T*)malloc(sizeof(BlockTableEntry_T)); + strcpy( fname, file.c_str() ); + entry->ptr = ptr; + entry->size = size; + entry->file = fname; + entry->line = line; + entry->next = NULL; + insert_record(ptr,entry); + } + return ptr; +} + +void * operator new(size_t size) throw(bad_alloc) { + void * ptr = malloc(size); + if(ptr == NULL) + { + throw bad_alloc(); + } + else + { + BlockTableEntry_T* entry = (BlockTableEntry_T*)malloc(sizeof(BlockTableEntry_T)); + entry->ptr = ptr; + entry->size = size; + entry->file = NULL; + entry->line = 0; + entry->next = NULL; + insert_record(ptr,entry); + } + return ptr; +} + +void operator delete(void * p) { + free(p); + erase_record(p); +} + +#endif diff --git a/src/cork.h b/src/cork.h new file mode 100644 index 0000000..1aa8ab6 --- /dev/null +++ b/src/cork.h @@ -0,0 +1,18 @@ +#ifndef CORK_H +#define CORK_H + +#ifdef DETECT_MEM_LEAKS + #include + typedef unsigned int size_t; + + void Cork_ReportMemoryLeaks(void); + void * operator new (size_t size, std::string file, unsigned int line); + #define TBL_SIZE 512 + #define REPORT_LEAKS() Cork_ReportMemoryLeaks() + #define _new new (__FILE__,__LINE__) +#else + #define REPORT_LEAKS() + #define _new new +#endif + +#endif