diff --git a/unix/alloc.c b/unix/alloc.c index afde1741..b2512b20 100644 --- a/unix/alloc.c +++ b/unix/alloc.c @@ -1,27 +1,55 @@ // 7 april 2015 -#include +#include #include "uipriv_unix.h" +static GHashTable *allocsizes; // map[*void]*size_t + +void initAlloc(void) +{ + allocsizes = g_hash_table_new(g_direct_hash, g_direct_equal); +} + void *uiAlloc(size_t size) { void *out; + size_t *s; out = g_malloc0(size); + if (g_hash_table_lookup(allocsizes, out) != NULL) + complain("already have a size for %p in uiAlloc()", out); + s = g_new0(size_t, 1); + *s = size; + g_hash_table_insert(allocsizes, out, s); return out; } -void *uiRealloc(void *p, size_t size) +void *uiRealloc(void *p, size_t new) { void *out; + size_t *s; if (p == NULL) - return uiAlloc(size); - // TODO fill with 0s - out = g_realloc(p, size); + return uiAlloc(new); + out = g_realloc(p, new); + s = (size_t *) g_hash_table_lookup(allocsizes, p); + if (s == NULL) + complain("no size found for %p in uiRealloc()", p); + if (new <= *s) + memset(((uint8_t *) out) + *s, 0, new - *s); + *s = new; + g_hash_table_remove(allocsizes, p); + g_hash_table_insert(allocsizes, out, s); return out; } void uiFree(void *p) { + size_t *s; + g_free(p); + s = (size_t *) g_hash_table_lookup(allocsizes, p); + if (s == NULL) + complain("no size found for %p in uiFree()", p); + g_hash_table_remove(allocsizes, p); + g_free(s); } diff --git a/unix/main.c b/unix/main.c index b86feb36..563cd5c6 100644 --- a/unix/main.c +++ b/unix/main.c @@ -14,6 +14,7 @@ const char *uiInit(uiInitOptions *o) g_error_free(err); return msg; } + initAlloc(); return NULL; } diff --git a/unix/uipriv_unix.h b/unix/uipriv_unix.h index 99577e42..b3ff92cd 100644 --- a/unix/uipriv_unix.h +++ b/unix/uipriv_unix.h @@ -14,3 +14,6 @@ // menu.c extern GtkWidget *makeMenubar(uiWindow *); extern void freeMenubar(GtkWidget *); + +// alloc.c +extern void initAlloc(void);