/* A simple heap manager, Louden, Figure. 7.19. */ #define NULL 0 #define MEMSIZE 8096 /* total memory size */ typedef double Align; /* unit size */ typedef union header { struct { union header *next; unsigned usedsize; unsigned freesize; } s; Align a; } Header; static Header mem[MEMSIZE]; /* memory units */ static Header *memptr = NULL; /* start pointer */ void * malloc(unsigned nbytes) { Header *p, *newp; unsigned nunits; nunits = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1; /* initialise heap */ if (memptr == NULL) { memptr->s.next = memptr = mem; memptr->s.usedsize = 1; memptr->s.freesize = MEMSIZE-1; } /* find first big enough block */ for (p=memptr; (p->s.next!=memptr) && (p->s.freesizes.next); /* no block big enough? */ if (p->s.freesize < nunits) return NULL; /* split found block */ newp = p + p->s.usedsize; newp->s.usedsize = nunits; newp->s.freesize = p->s.freesize - nunits; newp->s.next = p->s.next; p->s.freesize = 0; p->s.next = newp; /* set start pointer to new block */ memptr = newp; return (void *) (newp + 1); } void free(void *ap) { Header *bp, *p, *prev; /* find predecessor of block to free */ bp = (Header *) ap - 1; for (prev=memptr, p=memptr->s.next; (p!=bp) && (p!=memptr); prev=p, p=p->s.next); /* list corrupted? */ if (p!=bp) return; /* add block to predecessor */ prev->s.freesize += p->s.usedsize + p->s.freesize; prev->s.next = p->s.next; memptr = prev; }