Mercurial > repo
view src/ploki/xmalloc.c @ 8123:9df4aeaac079
<moon_> ` med il 1 \'lol this is a test\' testcmd
author | HackBot |
---|---|
date | Wed, 25 May 2016 00:31:41 +0000 |
parents | ac0403686959 |
children |
line wrap: on
line source
#include "config.h" #include "main.h" #include "xmalloc.h" #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #ifdef DEBUG_MALLOC #define IF_DB(x) x #else #define IF_DB(x) #endif static struct node { void *ptr; struct node *prev, *next; size_t size; #if DEBUG_P const char *file; unsigned line; #endif } *Root; #if 0 int xdump(void) { struct node *p; fprintf(stderr, ":%p\n", Root); for (p = Root; p; p = p->next) { fprintf(stderr, "\\<%p [%p]%p %p>\n", p->prev, p, p->ptr, p->next); assert(p != p->next); } fprintf(stderr, "\n"); return 0; } #endif void xend(void) { struct node *p; while ((p = Root)) { #if DEBUG_P unsigned char *ptr; for (ptr = p->ptr; memcmp(ptr, &p, sizeof p); ++ptr) ; ptr += sizeof p; fprintf(stderr, "%s: autofreeing pointer %p (%p) from %s:%u\n", Prog, p->ptr, (void *)ptr, p->file, p->line); #else fprintf(stderr, "%s: autofreeing pointer %p\n", Prog, p->ptr); #endif free(p->ptr); assert(Root != p->next); Root = p->next; free(p); } } #define XFACTOR(size) ((sizeof (struct node *) - 1) / (size) + 1u) #if DEBUG_P void *(xrealloc)(void *optr, size_t nmemb, const char *file, unsigned line) { #else void *xrealloc(void *optr, size_t nmemb) { #endif struct node *p; size_t k; size_t size; unsigned char *r; void *ptr; assert(optr != NULL); memcpy(&p, (unsigned char *)optr - sizeof Root, sizeof p); size = p->size; k = XFACTOR(size) * size; if (!(ptr = realloc(p->ptr, size * nmemb + k))) { fprintf(stderr, "%s: realloc(%p, %lu): %s\n", Prog, ptr, (unsigned long)(nmemb * size), strerror(errno)); abort(); } r = (unsigned char *)ptr + k; #if DEBUG_P IF_DB(fprintf(stderr, "%s: xrealloc(%zu): %p (%p) from %s:%u -> %p (%p) from %s:%u\n", Prog, nmemb, p->ptr, optr, p->file, p->line, ptr, r, file, line)); p->file = file; p->line = line; #endif p->ptr = ptr; return r; } #if DEBUG_P void *(xmalloc)(size_t nmemb, size_t size, const char *file, unsigned line) { #else void *xmalloc(size_t nmemb, size_t size) { #endif struct node *p; size_t k; unsigned char *r; if ((p = malloc(sizeof *p))) { k = XFACTOR(size) * size; if (!(p->ptr = malloc(size * nmemb + k))) { free(p); goto failure; } } else failure: { fprintf(stderr, "%s: malloc(%lu): %s\n", Prog, (unsigned long)(nmemb * size), strerror(errno)); abort(); } #if DEBUG_P memset(p->ptr, 'U', k); #endif r = (unsigned char *)p->ptr + k; memcpy(r - sizeof Root, &p, sizeof p); p->size = size; p->prev = NULL; p->next = Root; #if DEBUG_P p->file = file; p->line = line; IF_DB(fprintf(stderr, "%s: xmalloc(%zu, %zu): %p (%p) from %s:%u\n", Prog, nmemb, size, p->ptr, r, file, line)); #endif if (Root) { Root->prev = p; } Root = p; return r; } #if 0 #if DEBUG_P void *(xcalloc)(size_t nmemb, size_t size, const char *file, unsigned line) { void *const p = xmalloc(nmemb, size, file, line); #else void *xcalloc(size_t nmemb, size_t size) { void *const p = xmalloc(nmemb, size); #endif memset(p, '\0', nmemb * size); return p; } #endif void xfree(void *ptr) { struct node *p; if (!ptr) return; memcpy(&p, (unsigned char *)ptr - sizeof Root, sizeof p); assert(p != NULL); DEBUG(memset((unsigned char *)ptr - sizeof Root, 'F', sizeof Root)); if (p->next) { p->next->prev = p->prev; } if (p->prev) { p->prev->next = p->next; } else { assert(p == Root); Root = Root->next; } #if DEBUG_P IF_DB(fprintf(stderr, "%s: xfree(): %p (%p) from %s:%u\n", Prog, p->ptr, ptr, p->file, p->line)); #endif free(p->ptr); free(p); }