Mercurial > repo
view src/ploki/xmalloc.c @ 8427:1fc808cd5b1f
<b_jonas> learn can\'t is the most frequent word whose pronunciation varies between /\xc9\x91\xcb\x90/ and /\xc3\xa6/ depending on dialect. The list is: advance after answer ask aunt brass can\'t cast castle chance class command dance demand draft enhance example fast father glass graph grass half last laugh mask master nasty pass past path plant rather sample shan\'t staff task vast
author | HackBot |
---|---|
date | Thu, 09 Jun 2016 21:28:47 +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); }