struct memblock { int size; unsigned char magic; unsigned char occupied; struct memblock *next; struct memblock *prev; }; #define HEADER_SIZE (sizeof(struct memblock)) #define DELTA 20 #define MEM_MAGIC 0xa5 #define WORDSIZE 4 #define WORD_ALIGN(n) (((n) + WORDSIZE - 1) & -WORDSIZE) struct memblock block_chain; #define HEAP_SIZE 10000 char memory_heap[HEAP_SIZE]; void initialize_memory() { struct memblock *h; h = (struct memblock *)memory_heap; block_chain.size = sizeof(block_chain); block_chain.magic = MEM_MAGIC; block_chain.occupied = 1; block_chain.next = block_chain.prev = h; h->size = HEAP_SIZE; h->magic = MEM_MAGIC; h->occupied = 0; h->next = h->prev = & block_chain; } void *allocate_block(int size) { struct memblock *p, *s; int nbytes; nbytes = WORD_ALIGN(size + HEADER_SIZE); for (p = block_chain.next; p != &block_chain; p = p->next){ if(!p->occupied && p->size >= nbytes){ if (p->size - nbytes > DELTA){ s = (struct memblock *)((char *)p + nbytes); s->size = p->size - nbytes; s->magic = MEM_MAGIC; s->occupied = 0; p->next->prev = s; s->next = p->next; p->next = s; s->prev = p; p->size = nbytes; p->occupied = 1; } else p->occupied =1; return (char *)p + HEADER_SIZE; } } return NULL; } void free_block(void *block) { struct memblock *mem; mem = (struct memblock *)((char *)block - HEADER_SIZE); if(mem->magic != MEM_MAGIC) return; if (! mem->prev->occupied){ mem->next->prev = mem->prev; mem->prev->next = mem->next; mem->prev->size += mem->size; mem = mem->prev; } if(! mem->next->occupied){ mem->next->next->prev = mem; mem->size += mem->next->size; mem->next = mem->next->next; } mem->occupied = 0; }