#include #include #include #include struct debug_header { const char *f; unsigned int l; size_t s; struct debug_header *next, *prev; }; typedef struct debug_header d_header; d_header *d_head; void * f_debug_mem_malloc(size_t s, const char *f, unsigned int l) { d_header *m = malloc(s + sizeof(*m)); /* fprintf(stdout, "%s:%u: malloc(%zi)\n", f, l, s); */ if (m == NULL) return m; m->f = f; m->l = l; m->s = s; m->next = d_head; if (d_head) m->next->prev = m; m->prev = NULL; d_head = m; return m+1; } void f_debug_mem_free(void *s, const char *f, unsigned int l) { d_header *m; if (s != NULL) { m = (d_header *)s - 1; m->s = ~m->s; if (m->prev == NULL) { assert(d_head == m); d_head = m->next; } else { m->prev->next = m->next; } if (m->next) m->next->prev = m->prev; /* fprintf(stdout, "%s:%u: free()\n", f, l); */ free(m); } } void * f_debug_mem_realloc(void *x, size_t s, const char *f, unsigned int l) { d_header *m; void *q; if (x == NULL) { return f_debug_mem_malloc(s, f, l); } else if (s == 0) { f_debug_mem_free(x, f, l); return NULL; } else { m = (d_header *)x - 1; if (s <= m->s) return x; q = f_debug_mem_malloc(s, f, l); if (q) { memcpy(q, x, m->s); f_debug_mem_free(x, f, l); } return q; } } void f_debug_mem_show() { d_header *m = d_head; while (m) { fprintf(stdout, "%s:%u: %zd bytes at %p\n", m->f, m->l, m->s, (void*)(m+1)); m = m->next; } } #include "debug.h"