My implementation of a Memory Manager
MemoryManager.h
#ifndef _MEMORY_MANAGER_H #define _MEMORY_MANAGER_H #include
MemoryManager.cpp
#include "MemoryManager.h" MemoryManager* MemoryManager::m_pInstance = NULL; MemoryManager::MemoryManager() { // Allocate a single block of memory of size 1MB m_pMemoryHeap = _aligned_malloc(MemoryManagerHeap, 4); m_AllocatedSize = 0; m_SmallBlockAllocators.insert(std::make_pair(4, SmallBlockAllocator::Create(4, 100))); m_SmallBlockAllocators.insert(std::make_pair(8, SmallBlockAllocator::Create(8, 100))); m_SmallBlockAllocators.insert(std::make_pair(16, SmallBlockAllocator::Create(16, 100))); } MemoryManager::~MemoryManager() { _aligned_free(m_pMemoryHeap); SmallBlockAllocatorMap::iterator SBAIterator = m_SmallBlockAllocators.begin(); for (size_t iterator = 0; iterator < m_SmallBlockAllocators.size(); iterator++) { SmallBlockAllocator::Destroy(m_SmallBlockAllocators[iterator]); } } void MemoryManager::CreateMemoryManager() { if (m_pInstance == NULL) { m_pInstance = new MemoryManager(); } } void MemoryManager::DestroyMemoryManager() { assert(m_pInstance); delete m_pInstance; m_pInstance = NULL; } void* MemoryManager::alloc(size_t i_size) { assert(m_pInstance); // Check if we can use the Small Block Allocators to allocate memory. SmallBlockAllocatorMap::iterator itSBA = m_pInstance->m_SmallBlockAllocators.find(i_size); if (itSBA != m_pInstance->m_SmallBlockAllocators.end()) { return itSBA->second->alloc(i_size); } // Size is bigger for Small Block Allocators to handle // Memory Manager will allocate the memory if (m_pInstance->m_FreeBlocks.size() == 0) { m_pInstance->m_AllocatedSize += i_size; m_pInstance->m_OutStandingBlocks.insert(std::make_pair(m_pInstance->m_pMemoryHeap, i_size)); void *pNextFreePointer = static_cast(m_pInstance->m_pMemoryHeap) + i_size; if (static_cast (pNextFreePointer) < static_cast (m_pInstance->m_pMemoryHeap) + MemoryManagerHeap) { m_pInstance->m_FreeBlocks.insert(std::make_pair(pNextFreePointer, MemoryManagerHeap - m_pInstance->m_AllocatedSize)); } return m_pInstance->m_pMemoryHeap; } else if (i_size <= MemoryManagerHeap - m_pInstance->m_AllocatedSize) { FreeBlockMap::iterator itFreeBlocks = m_pInstance->m_FreeBlocks.begin(); for (; itFreeBlocks != m_pInstance->m_FreeBlocks.end(); itFreeBlocks++) { if (itFreeBlocks->second >= i_size) { m_pInstance->m_AllocatedSize += i_size; m_pInstance->m_OutStandingBlocks.insert(std::make_pair(itFreeBlocks->first, i_size)); void *pNextFreePointer = static_cast (itFreeBlocks->first) + i_size; if (itFreeBlocks->second - i_size != 0) m_pInstance->m_FreeBlocks.insert(std::make_pair(pNextFreePointer, itFreeBlocks->second - i_size)); void *pMemoryPointer = itFreeBlocks->first; m_pInstance->m_FreeBlocks.erase(itFreeBlocks); return pMemoryPointer; } } return NULL; } else return NULL; } void MemoryManager::dealloc(void* i_pBasePointer) { assert(m_pInstance); OutStandingBlockMap::iterator itOutStandingBlock = m_pInstance->m_OutStandingBlocks.find(i_pBasePointer); if (itOutStandingBlock != m_pInstance->m_OutStandingBlocks.end()) { m_pInstance->m_FreeBlocks.insert(std::make_pair(i_pBasePointer, itOutStandingBlock->second)); m_pInstance->m_OutStandingBlocks.erase(itOutStandingBlock); if (m_pInstance->m_FreeBlocks.size() >= 2) CoalesceFreeBlocks(i_pBasePointer); } } void MemoryManager::CoalesceFreeBlocks(void* i_pBasePointer) { assert(m_pInstance); FreeBlockMap::iterator itFreeBlock = m_pInstance->m_FreeBlocks.find(i_pBasePointer); void *pAdjacentPointer = static_cast (i_pBasePointer)+itFreeBlock->second; FreeBlockMap::iterator itAdjacentFreeBlock = m_pInstance->m_FreeBlocks.find(pAdjacentPointer); while (itAdjacentFreeBlock != m_pInstance->m_FreeBlocks.end()) { itFreeBlock->second += itAdjacentFreeBlock->second; m_pInstance->m_FreeBlocks.erase(itAdjacentFreeBlock); pAdjacentPointer = static_cast (i_pBasePointer)+itFreeBlock->second; itAdjacentFreeBlock = m_pInstance->m_FreeBlocks.find(pAdjacentPointer); } if (m_pInstance->m_FreeBlocks.size() >= 2) { FreeBlockMap::iterator itFreeBlockIterator = m_pInstance->m_FreeBlocks.begin(); for (; itFreeBlockIterator != m_pInstance->m_FreeBlocks.end(); itFreeBlockIterator++) { pAdjacentPointer = static_cast (itFreeBlockIterator->first)+itFreeBlockIterator->second; if (pAdjacentPointer == i_pBasePointer) { itFreeBlockIterator->second += itFreeBlock->second; m_pInstance->m_FreeBlocks.erase(itFreeBlock); } } } }