// 4 december 2014 #include "uipriv_windows.hpp" typedef std::vector byteArray; static std::map heap; static std::map types; void initAlloc(void) { // do nothing } void uninitAlloc(void) { std::ostringstream oss; std::string ossstr; // keep alive, just to be safe if (heap.size() == 0) return; for (const auto &alloc : heap) // note the void * cast; otherwise it'll be treated as a string oss << (void *) (alloc.first) << " " << types[alloc.second] << "\n"; ossstr = oss.str(); printf("data leak: %s\n", ossstr.c_str()); userbug("Some data was leaked; either you left a uiControl lying around or there's a bug in libui itself. Leaked data:\n%s", ossstr.c_str()); } #define rawBytes(pa) (&((*pa)[0])) void *uiAlloc(size_t size, const char *type) { byteArray *out; out = new byteArray(size, 0); heap[rawBytes(out)] = out; types[out] = type; return rawBytes(out); } void *uiRealloc(void *_p, size_t size, const char *type) { uint8_t *p = (uint8_t *) _p; byteArray *arr; if (p == NULL) return uiAlloc(size, type); arr = heap[p]; arr->resize(size, 0); heap.erase(p); heap[rawBytes(arr)] = arr; return rawBytes(arr); } void uiFree(void *_p) { uint8_t *p = (uint8_t *) _p; if (p == NULL) implbug("attempt to uiFree(NULL)"); types.erase(heap[p]); delete heap[p]; heap.erase(p); }