4 * Memory routines with out-of-memory checking.
6 * Copyright 1996 Derek B. Noonburg
17 typedef struct _GMemHdr {
20 struct _GMemHdr *next;
23 #define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
24 #define gMemTrlSize (sizeof(long))
27 #define gMemDeadVal 0xdeadbeefdeadbeef
29 #define gMemDeadVal 0xdeadbeef
32 /* round data size so trailer will be aligned */
33 #define gMemDataSize(size) \
34 ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
37 #define gMemListShift 4
38 #define gMemListMask (gMemNLists - 1)
39 static GMemHdr *gMemList[gMemNLists] = {
40 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
41 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
42 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
43 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
44 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
45 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
46 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
50 static int gMemIndex = 0;
51 static int gMemAlloc = 0;
53 #endif /* DEBUG_MEM */
55 void *gmalloc(int size) {
66 size1 = gMemDataSize(size);
67 if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
68 fprintf(stderr, "Out of memory\n");
72 data = (void *)(mem + gMemHdrSize);
73 trl = (long *)(mem + gMemHdrSize + size1);
75 hdr->index = gMemIndex++;
76 lst = ((int)hdr >> gMemListShift) & gMemListMask;
77 hdr->next = gMemList[lst];
80 for (p = (long *)data; p <= trl; ++p)
88 if (!(p = malloc(size))) {
89 fprintf(stderr, "Out of memory\n");
96 void *grealloc(void *p, int size) {
108 hdr = (GMemHdr *)((char *)p - gMemHdrSize);
111 memcpy(q, p, size < oldSize ? size : oldSize);
126 q = realloc(p, size);
130 fprintf(stderr, "Out of memory\n");
137 void gfree(void *p) {
141 GMemHdr *prevHdr, *q;
146 hdr = (GMemHdr *)((char *)p - gMemHdrSize);
147 lst = ((int)hdr >> gMemListShift) & gMemListMask;
148 for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) {
154 prevHdr->next = hdr->next;
156 gMemList[lst] = hdr->next;
158 size = gMemDataSize(hdr->size);
159 trl = (long *)((char *)hdr + gMemHdrSize + size);
160 if (*trl != gMemDeadVal) {
161 fprintf(stderr, "Overwrite past end of block %d at address %p\n",
164 for (clr = (long *)hdr; clr <= trl; ++clr)
168 fprintf(stderr, "Attempted to free bad address %p\n", p);
178 void gMemReport(FILE *f) {
182 fprintf(f, "%d memory allocations in all\n", gMemIndex);
184 fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
185 fprintf(f, " index size\n");
186 fprintf(f, "-------- --------\n");
187 for (lst = 0; lst < gMemNLists; ++lst) {
188 for (p = gMemList[lst]; p; p = p->next)
189 fprintf(f, "%8d %8d\n", p->index, p->size);
192 fprintf(f, "No memory blocks left allocated\n");
197 char *copyString(char *s) {
200 s1 = (char *)gmalloc(strlen(s) + 1);