#include #include #include #include #include using namespace std; typedef size_t BlockSize; // Record for a free memory block struct MemBlock { BlockSize size; // Size of this block MemBlock *next; // Next free memory block }; // Pointer to the list of free blocks, sorted by starting address static MemBlock *free_list = NULL; // Substitute for malloc void *malloc(size_t size) { // How much memory do we need? size_t need = max(sizeof(MemBlock), size + sizeof(BlockSize)); // See if we already have a block that's large enough for (MemBlock **bptr = &free_list; *bptr; bptr = &((*bptr)->next)) { if ((*bptr)->size >= need) { // Remove the block from our free list BlockSize *p = (BlockSize *)(*bptr); *bptr = (*bptr)->next; // Skip past the size field and give away the whole block return p + 1; } } // Ask for memory that's just as big as we need BlockSize *p = (BlockSize *) sbrk(need); // Fill in the size field (for subsequent call to free) *p = need; // Return a pointer to the new memory return p + 1; } // Substitute for free void free(void *ptr) { // Get a pointer to the start of the node for our freelist MemBlock *block = (MemBlock *) (((BlockSize *)ptr) - 1); // Find where to put this block in the free list MemBlock **bptr = &free_list; while (*bptr && (void *)(*bptr) < block) bptr = &((*bptr)->next); // Link this block into the freelist block->next = *bptr; *bptr = block; } // Substitute for calloc void *calloc(size_t nmemb, size_t size) { // Allocate a sufficiently big block void *ptr = malloc(nmemb*size); // Fill fresh block of memory with zeros and return a pointer to it bzero(ptr, size); return ptr; } // We have to supply a realloc since client code may also expect to use it // This implementation doesn't offer any performance advantage over malloc/free void *realloc(void *ptr, size_t size) { // Recover the old size (so we know what to copy) size_t old_size = ((int *)ptr)[-1]; // Get a new buffer void *p2 = malloc(size); // Copy everything over memcpy(p2, ptr, old_size); // Free the old buffer and return the new one free(ptr); return p2; }