Very simplex, cross-platform methodology for detecting memory leaks in C programs
This simple code proves as a testament to those who suffer mem leaks but don't resolve them.
There is probably better out there. This should be laggy as heck in a real, big program. Although, for testing certain variables, this does justice.
Did you know? Using __LINE__ in your code is a macro that expands to the line number your code is on?
To use, follow this format:
size_t time = current_time();
some_expensive_function();
size_t time2 = current_time();
printf("%zu\n", time2 - time);
translated:
size_t size = _gather_size();
void* stuff = __malloc(sizeof(void*), __LINE__);
use_pointer(stuff);
function_that_should_free_pointer(stuff);
size_t end_size = _gather_size();
printf("%zu\n", end_size - size); // error if > 0
if(end_size - size != 0) {
vp_info info = _gather_get(end_size - 1);
fprintf(stderr,
"Warning: Line %zu ptr %p of type %s length %zu was not cleaned up!\n",
info->line, info->ptr, (info->ftype == 0 ? "MALLOC" : "CALLOC"), info->size);
}
Project Test Output
C:\git\MemLeeks>test
a 1
b 2
c 3
d 4
p1 00000000002DF380
p2 00000000002DF3D0
There are 3 malloc/calloc handles
On line 25 pointer 00000000002DF320 exists of type MALLOC length 40
On line 30 pointer 00000000002DF380 exists of type MALLOC length 8
On line 31 pointer 00000000002DF3D0 exists of type CALLOC length 8
Realloced 00000000002DF380 to 00000000005776C0
Cleaning environment!
There are 2 malloc/calloc handles
On line 51 pointer 00000000005776C0 exists of type MALLOC length 80
On line 31 pointer 00000000002DF3D0 exists of type CALLOC length 8
// enum tells about type of call made
typedef enum _FuncType {
MALLOC = 0,
CALLOC = 1
} FuncType;
// struct to uniformly hold data
typedef struct _vp_info {
void* ptr; // the pointer allocated
size_t size; // size of the pointer
size_t line; // the line, if using _malloc or _calloc, it is always 0
FuncType ftype; // malloc is 0, calloc is 1
} vp_info;
int _mem_leak_init(); - initalizes the inner dynamic array to record memory allocations void _mem_leak_close(); - deallocates the inner dynamic array
void* _malloc(size_t size); - appends a struct to a dynamic array, returns pointer to allocated memory
void* __malloc(size_t size, size_t line); - ^ and records line number
void* _calloc(size_t nmemb, size_t size); - appends a struct to a dynamic array, returns pointer to allocated memory
void* __calloc(size_t nmemb, size_t size, size_t line); - ^ and records line number
void* _realloc(void* ptr, size_t new_size); - reallocs a pointer, updates struct, returns pointer to allocated memory
void* __realloc(void* ptr, size_t new_size, size_t line); - ^ and records line number
void _free(void* ptr); - frees memory allocated and removes the record of dynamic memory allocation from the array
used to iterate through *allocs
- at end of program, take size
- at end of cleanup, take size
- if size1 != 0, you may have leakage
- if size2 != 0, you have leakage
- iterate through using _gather_get() the leaks
- fix the leaks
size_t _gather_size(); - returns the number of elements in the dynamic array (for iteration)
vp_info* _gather_get(size_t index); - returns the element at array index index in the dynamic array