4
* Memory routines with out-of-memory checking.
6
* Copyright 1996-2003 Glyph & Cog, LLC
19
typedef struct _GMemHdr {
23
struct _GMemHdr *next, *prev;
26
#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
27
#define gMemTrlSize (sizeof(long))
29
#define gMemMagic 0xabcd9999
32
#define gMemDeadVal 0xdeadbeefdeadbeefUL
34
#define gMemDeadVal 0xdeadbeefUL
37
/* round data size so trailer will be aligned */
38
#define gMemDataSize(size) \
39
((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
41
static GMemHdr *gMemHead = NULL;
42
static GMemHdr *gMemTail = NULL;
44
static int gMemIndex = 0;
45
static int gMemAlloc = 0;
46
static int gMemInUse = 0;
48
#endif /* DEBUG_MEM */
50
void *gmalloc(int size) GMEM_EXCEP {
56
unsigned long *trl, *p;
60
throw GMemException();
62
fprintf(stderr, "Invalid memory allocation size\n");
69
size1 = gMemDataSize(size);
70
if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
72
throw GMemException();
74
fprintf(stderr, "Out of memory\n");
79
data = (void *)(mem + gMemHdrSize);
80
trl = (unsigned long *)(mem + gMemHdrSize + size1);
81
hdr->magic = gMemMagic;
83
hdr->index = gMemIndex++;
90
gMemHead = gMemTail = hdr;
95
for (p = (unsigned long *)data; p <= trl; ++p) {
104
throw GMemException();
106
fprintf(stderr, "Invalid memory allocation size\n");
113
if (!(p = malloc(size))) {
115
throw GMemException();
117
fprintf(stderr, "Out of memory\n");
125
void *grealloc(void *p, int size) GMEM_EXCEP {
133
throw GMemException();
135
fprintf(stderr, "Invalid memory allocation size\n");
146
hdr = (GMemHdr *)((char *)p - gMemHdrSize);
149
memcpy(q, p, size < oldSize ? size : oldSize);
160
throw GMemException();
162
fprintf(stderr, "Invalid memory allocation size\n");
173
q = realloc(p, size);
179
throw GMemException();
181
fprintf(stderr, "Out of memory\n");
189
void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
196
if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
198
throw GMemException();
200
fprintf(stderr, "Bogus memory allocation size\n");
207
void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP {
217
if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
219
throw GMemException();
221
fprintf(stderr, "Bogus memory allocation size\n");
225
return grealloc(p, n);
228
void gfree(void *p) {
232
unsigned long *trl, *clr;
235
hdr = (GMemHdr *)((char *)p - gMemHdrSize);
236
if (hdr->magic == gMemMagic &&
237
((hdr->prev == NULL) == (hdr == gMemHead)) &&
238
((hdr->next == NULL) == (hdr == gMemTail))) {
240
hdr->prev->next = hdr->next;
242
gMemHead = hdr->next;
245
hdr->next->prev = hdr->prev;
247
gMemTail = hdr->prev;
250
gMemInUse -= hdr->size;
251
size = gMemDataSize(hdr->size);
252
trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
253
if (*trl != gMemDeadVal) {
254
fprintf(stderr, "Overwrite past end of block %d at address %p\n",
257
for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
262
fprintf(stderr, "Attempted to free bad address %p\n", p);
273
void gMemReport(FILE *f) {
276
fprintf(f, "%d memory allocations in all\n", gMemIndex);
278
fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
279
fprintf(f, " index size\n");
280
fprintf(f, "-------- --------\n");
281
for (p = gMemHead; p; p = p->next) {
282
fprintf(f, "%8d %8d\n", p->index, p->size);
285
fprintf(f, "No memory blocks left allocated\n");
290
char *copyString(char *s) {
293
s1 = (char *)gmalloc(strlen(s) + 1);