Mercurial > ~dholland > hg > ag > index.cgi
view anagram/support/myalloc.cpp @ 17:12171da8943f
Don't refer to CVS.
author | David A. Holland |
---|---|
date | Tue, 31 May 2022 01:56:37 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * AnaGram, A System for Syntax Directed Programming * Copyright 1993-1999 Parsifal Software. All Rights Reserved. * See the file COPYING for license and usage terms. * * myalloc.cpp - memory allocation wrappers */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "port.h" #include "assert.h" #include "myalloc.h" //#define INCLUDE_LOGGING #include "log.h" typedef struct { unsigned size, comp; } fence; static void check_mem(void *p) { if (p == NULL) { bailOut("Out of memory"); } } static fence make_fence(int n) { fence f; n -= 2*sizeof(fence); f.size = n; f.comp = ~n; return f; } static char longjmp_msg[128]; void *myalloc(unsigned n) { fence *ptr; fence *top, *bot; if (n == 0) { return NULL; } //myallocs++; n += 2*sizeof(fence); if (n&1) { n++; } bot = ptr = (fence *) malloc(n); check_mem(ptr); ptr = (bot + 1); top = (fence *)((char *)bot + n - sizeof(fence)); //*top = *bot = make_fence(n); *bot = make_fence(n); memcpy(top, bot, sizeof(fence)); //myallocBytes += n; return (void *) ptr; } void *myzalloc(unsigned n, unsigned size) { unsigned k = n*size; fence *ptr = (fence *) myalloc(k); memset(ptr, 0, k); return ptr; } static void *ersatz_realloc(void *bot, int n) { int m = *(int *) bot + 2*sizeof(fence); void *old_bot = bot; bot = malloc(n); if (bot == NULL) { return bot; } if (n < m) { m = n; } memmove(bot, old_bot, m); free(old_bot); return bot; } void *myrealloc(void *p, unsigned n, const char *file, int line) { fence *ptr; fence *top, *bot = (fence *) p; // , *oldbot; if (p == NULL) { ptr = (fence *) myalloc(n); return ptr; } ptr_ng(p, file, line); n += 2*sizeof(fence); if (n&1) { n++; } bot--; if (n > 64000) { bot = (fence *) ersatz_realloc(bot, n); } else { //myfreeBytes += bot->size; bot = (fence *) realloc(bot, n); //myallocBytes += n; } check_mem(bot); ptr = (bot + 1); top = (fence *)((char *)bot + n - sizeof(fence)); //*top = *bot = make_fence(n); *bot = make_fence(n); memcpy(top, bot, sizeof(fence)); return ptr; } char *mystrdup(const char *s) { assert(s != NULL); int k = strlen(s) + 1; char *c = ALLOCATE(k, char); return strcpy(c,s); } static int fence_ng(const void *f) { if (f == NULL) { return 3; } const fence *bot=(const fence *)f-1; if (bot->size != ~bot->comp) { return 1; } const fence *top = (const fence *) ((const char *)f + bot->size); //if (bot->size != top->size) { // return 2; //} //if (top->size != ~top->comp) { // return 2; //} if (memcmp(top, bot, sizeof(fence))) { return 2; } return 0; } int ptr_ok(void *f) { fence *bot=(fence *)f-1, *top; if (f == NULL) { return 0; } if (bot->size != ~bot->comp) { return 0; } top = (fence *)((char *)f + bot->size); if ((bot->size ^ top->size) | (bot->comp ^ top->comp)) { return 0; } return 1; } void ptr_ng(const void *ptr, const char *file, int line) { int flag = fence_ng(ptr); if (flag) { flag = " BTN"[flag]; } if (!flag || no_assertions) { return; } no_assertions = 1; snprintf(longjmp_msg, sizeof(longjmp_msg), "AnaGram internal error: bad pointer %p (%c), %s line %d", ptr, flag, file, line); LOGSECTION("Bad array fence"); LOGSTACK; LOGV(longjmp_msg); bailOut(longjmp_msg); } void size_ok(const void *ptr, unsigned n, const char *file, int line) { const fence *fp = (const fence *) ptr; check_stack; fp--; if (n <= fp->size || no_assertions) { return; } no_assertions = 1; snprintf(longjmp_msg, sizeof(longjmp_msg), "AnaGram internal error: bad size %u, %s line %d", n, file, line); LOGSECTION("size_ok"); LOGSTACK; LOGV(longjmp_msg); bailOut(longjmp_msg); } void myfree(void *ptr, const char *file, int line) { if (ptr == NULL) { return; } //myfrees++; ptr_ng(ptr, file, line); fence *base = (fence *)ptr - 1; //myfreeBytes += base->size + 2*sizeof(fence); base->size = 0; free(base); } #if 0 void *operator new(size_t size) { //newCalls++; void *pointer = myalloc(size); return pointer; } void operator delete(void *p) { //deleteCalls++; DEALLOCATE(p); } void *operator new[](size_t size) { //newArrayCalls++; void *pointer = myalloc(size); return pointer; } void operator delete[](void *p) { //deleteArrayCalls++; DEALLOCATE(p); } #endif