#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