#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
// Use __FILE__ __LINE__ __function__
typedef struct Alloc_Info {
Alloc_Info *next;
const char *type;
void *pointer;
size_t size;
size_t free_count;
}Alloc_Info;
Alloc_Info alloc_first = {0};
Alloc_Info *alloc_last = &alloc_first;
void *malloc_debug(size_t size, const char *type) {
void *result = malloc(size);
alloc_last->next = (Alloc_Info *)malloc(sizeof(Alloc_Info));
alloc_last->type = type;
alloc_last->pointer = result;
alloc_last->size = size;
alloc_last->free_count = 0;
alloc_last = alloc_last->next;
return result;
}
#define malloc(type) ((type *)malloc_debug(sizeof(type), #type))
void free_debug(void *v) {
for(Alloc_Info *l = &alloc_first; l->next != 0; l = l->next) {
if(l->pointer == v) {
if(l->free_count == 0) {
// free(v); // I need to hold on to memory to prevent reuse
}
l->free_count += 1;
return;
}
}
assert(0 && "Pointer was never allocated"); // Store this to a list.
}
#define free(value) free_debug(value)
void alloc_finish() {
printf("Dangling pointers\n");
for(Alloc_Info l = alloc_first; l.next != 0; l = *l.next) {
if(l.free_count == 0) {
printf("\tptr: %p len: %lu type: %s\n", l.pointer, l.size, l.type);
}
}
printf("Multiple free'd pointers\n");
for(Alloc_Info l = alloc_first; l.next != 0; l = *l.next) {
if(l.free_count > 1) {
printf("\tptr: %p len: %lu type: %s free count: %lu\n", l.pointer, l.size, l.type, l.free_count);
}
}
}
int main() {
int *a = malloc(int);
double *b = malloc(double);
Alloc_Info *c = malloc(Alloc_Info);
short *d = malloc(short);
free(a);
free(b);
free(c);
free(c);
free(c);
//free(d);
alloc_finish();
return 0;
}