#include #include #include // 14 LOC in i realized this is just shitty raii... // Still finishing it we ball #ifndef MEMSAFE_ONCE #define MEMSAFE_ONCE void safefree(void *x); void *safemalloc(size_t x); #endif #ifdef MEMSAFE_PLEASE typedef struct { void **ptrs; size_t cnt; size_t cap; } memsafe_allocation; struct { memsafe_allocation *allocs; size_t cnt; size_t cap; } memsafe_allocstack = {0}; #define memsafe_pushhist do {\ if (memsafe_allocstack.cap == 0) { \ memsafe_allocstack.allocs = malloc(8*sizeof(memsafe_allocation)); \ memsafe_allocstack.cap = 8; \ memsafe_allocstack.cnt = 0; \ } \ if (memsafe_allocstack.cnt >= memsafe_allocstack.cap) { \ memsafe_allocstack.allocs = realloc(memsafe_allocstack.allocs, \ 2*memsafe_allocstack.cap*sizeof(memsafe_allocation)); \ memsafe_allocstack.cap *= 2; \ } \ memsafe_allocstack.allocs[memsafe_allocstack.cnt++] = \ (memsafe_allocation) { \ .ptrs = malloc(64*sizeof(void*)), \ .cnt = 0, \ .cap = 64 \ }; \ } while(0) #define memsafe_pophist do {\ memsafe_allocation a = memsafe_allocstack.allocs \ [--memsafe_allocstack.cnt]; \ for (int i = 0; i < a.cnt; ++i) { \ free(a.ptrs[i]); \ } \ free(a.ptrs); \ } while(0) void safefree(void *x) { assert(0 && "No manual freeing we do memory safety here"); } void *safemalloc(size_t x) { memsafe_allocation *a = &memsafe_allocstack.allocs[memsafe_allocstack.cnt-1]; if (a->cnt >= a->cap) { a->ptrs = realloc(a->ptrs, 2*a->cap*sizeof(void*)); a->cap *= 2; } void *p = malloc(x); a->ptrs[a->cnt++] = p; return p; } #endif