Я провел небольшое исследование по разработке Game Engine и наконец начал пытаться написать Memorymanager.Я получил идею из Книги Дизайна игрового движка от Eberly.В конструкторе я выделяю блок памяти и добавляю к нему верхний и нижний колонтитулы, которые имеют атрибут size и используются.Но теперь я получаю доступ к письму.Я уже что-то слышал о том, что указатели являются константными и доступны только для чтения, но я понятия не имею, как я могу это исправить.
Вот файл MemoryManager.h:
// MemoryManager.h - Header file //
#ifndef H_MemoryManager
#define H_MemoryManager
#include "IMemoryManager.h"
class HeaderBlock
{
public:
bool Used;
unsigned int Size;
HeaderBlock* Prev;
HeaderBlock* Next;
};
class FooterBlock
{
public:
bool Used;
unsigned int Size;
};
class MemoryManager : public IMemoryManager
{
private:
int m_MemoryBudget;
char* m_FullMemory;
HeaderBlock* m_FreeBlock;
int m_hsize; // Size of the header
int m_fsize; // Size of the footer
int m_hfsize; // Size of the HeaderandFooter
public:
// Constructor and Destructor
MemoryManager(int Budget);
virtual ~MemoryManager();
// Functions
virtual char* Allocate(unsigned int RequestSize);
virtual char* Deallocate(char* pDeallocate);
HeaderBlock* SearchByPolicy(unsigned int RequestSize);
};
#endif
Вот реализация Конструктора:
MemoryManager::MemoryManager(int Budget)
{
m_MemoryBudget = Budget;
m_FullMemory = (char*)malloc(m_MemoryBudget);
m_hsize = sizeof(HeaderBlock);
m_fsize = sizeof(FooterBlock);
m_hfsize = m_hsize + m_fsize;
HeaderBlock* header = (HeaderBlock*)m_FullMemory;
header->Used = false;
header->Size = m_MemoryBudget;
FooterBlock* footer = (FooterBlock*)(m_FullMemory + m_MemoryBudget - m_fsize);
footer->Used = false;
footer->Size = m_MemoryBudget;
header->Prev = header;
header->Next = header;
m_FreeBlock = (HeaderBlock*)m_FullMemory;
}
А вот метод выделения, где я получаю ошибку при ошибке
usedHeader->Used = true;
usedFooter->Used = true;
freeHeader->Used = false;
freeFooter->Used = false; // HERE I GET THE EXCEPTION
char* MemoryManager::Allocate(unsigned int RequestSize)
{
HeaderBlock* header = SearchByPolicy(RequestSize);
if(header == NULL)
{
return NULL;
}
unsigned int Size = header->Size;
FooterBlock* footer = (FooterBlock*)((header + Size - m_fsize));
// 1.The size to be allocated fits EXACTLY in the Block pointed by header.
if(Size == RequestSize + m_hfsize)
{
char* allocated = (char*)header + m_hsize;
header->Used = true;
footer->Used = true;
if(header->Next == header)
{
// This is the only block on the free list
m_FreeBlock = 0;
}
else
{
m_FreeBlock->Prev->Next = m_FreeBlock->Next;
m_FreeBlock->Next->Prev = m_FreeBlock->Prev;
m_FreeBlock = m_FreeBlock->Next;
}
return allocated;
}
// 2. The block has more storage than is needed for the allocation request.
if(Size >= RequestSize + 2*m_hfsize)
{
char* allocated = (char*)(header + m_hsize);
// Split the block in a "Used"-Block and a "Free"-Block
HeaderBlock* usedHeader = header;
FooterBlock* usedFooter = (FooterBlock*)(header + m_hsize + RequestSize);
HeaderBlock* freeHeader = (HeaderBlock*)(usedFooter + m_fsize);
FooterBlock* freeFooter = footer;
usedHeader->Used = true;
usedFooter->Used = true;
freeHeader->Used = false;
freeFooter->Used = false;
unsigned int usedSize = RequestSize + m_hfsize;
freeHeader->Size = header->Size - usedSize;
usedHeader->Size = usedSize;
freeHeader->Prev = header->Prev;
freeHeader->Next = header->Next;
m_FreeBlock = freeHeader;
return allocated;
}
// 3. The block has more storage then the Request, but to less to divide into two blocks.
char* allocated = (char*)header + m_hsize;
header->Used = true;
footer->Used = true;
//Detach from the free list;
if(header->Next == header)
{
// This is the only block on the free list
m_FreeBlock = 0;
}
else
{
m_FreeBlock->Prev->Next = m_FreeBlock->Next;
m_FreeBlock->Next->Prev = m_FreeBlock->Prev;
m_FreeBlock = m_FreeBlock->Next;
}
return allocated;
}
Я уже проверил, возвращает ли функция SearchByPolicy действительный указатель ион возвращает верный указатель, если может найти больший блок памяти, чем запрос.
Надеюсь, вы мне поможете!