Mercurial > repo
view src/ploki/xmalloc.c @ 5556:f2e89077ff1d
<oerjan> learn Turkey was the center of an empire that gobbled up much of Eastern Europe and the Middle East, something which brought them into conflict with Ostrich. In the 19th century the overstuffed empire started declining, and after the Great War it was cut up like so much Shish Kebab.
author | HackBot |
---|---|
date | Fri, 12 Jun 2015 06:39:15 +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); }