Listing 2: MemoryAllocator member

#include "include/allocmem.h"
     
#define TRAILING_ 0x55555555
#define HEADING_ 0x55555555
     
MemoryAllocator::MemoryAllocator(uint unit_size, uint block_size)
    : _allocated_size (max(unit_size, sizeof(Free))), 
    _requested_size(unit_size),
    _block_size(block_size),
    _num_allocated_blocks(0),
    _allocated_blocks(0),
    _free(0),
    _debug (false)
    {}
     
MemoryAllocator::MemoryAllocator(uint unit_size, uint block_size,
    bool debug)
    : _allocated_size(max(unit_size, sizeof(Free))), 
    _requested_size(unit_size),
    _block_size(block_size),
    _num_allocated_blocks(0),
    _allocated_blocks(0),
    _free(0),
    _debug(debug)
    {
    if (_debug)
        _allocated_size += 2 * sizeof(int);
    }
     
MemoryAllocator::~MemoryAllocator()
    {
    for (int k = 0; k < _num_allocated_blocks; ++k)
        {
        ::operator delete(_allocated_blocks[k]); 
        }
    ::operator delete(_allocated_blocks); 
    }
     
void
MemoryAllocator::more() throw(char*)
    {
    Free* new_block = (Free*)
        ::operator new(_allocated_size *_block_size);
    void** new_blocks = (void**) ::operator new(sizeof(void*)
        * (_num_allocated_blocks + 1));
    int last_element = _block_size - 1;
    if (!new_block || !new_blocks)
        throw("Memory allocation failed.");
    if (_allocated_blocks)
        {
        memcpy(new_blocks, _allocated_blocks, sizeof(void*)
            * _num_allocated_blocks);
        ::operator delete(_allocated_blocks); 
        }
    _allocated_blocks = new_blocks;
    _allocated_blocks[_num_allocated_blocks++] = new_block; 
    _free = new_block;
     
    for (int k = 0; k<last_element; ++k, new_block = new_block->next)
        {
        new_block->next = (Free*) ((char*) new_block
            + _allocated_size);
        }
    new_block->next = 0;
    }
     
void*
MemoryAllocator::debug_correct(void*& storage)
    {
    *(int*) storage = HEADING_;
    storage = (int*) storage + 1;
    *(int*) ((char*) storage + _requested_size) = TRAILING_; 
    return storage;
    }
     
void*
MemoryAllocator::debug_check(void*& storage) throw(char*)
    {
    int* tail = (int*) ((char*) storage + _requested_size); 
    int* head = (int*) (storage = (int*) storage - 1);
     
    if (*tail != TRAILING_)
        throw("Block tail has been overrun.");
    if (*head !=  HEADING_)
        throw("Block header has been overrun.");
    return storage;
    }
//End of File