Я написал класс для распределителя пула и протестировал его с некоторыми базовыми структурами, sf::Texture
и, похоже, работает правильно. Однако, когда я использую его, чтобы скопировать sf::Font
в выделенный блок я получаю следующее сообщение об ошибке:Как скопировать sf :: Шрифт в память выделенного пула?
Exception thrown at 0x0F19009E (sfml-graphics-d-2.dll) in ChernoGame.exe: 0xC0000005: Access violation writing location 0xCDCDCDCD.
код, который выдает эту ошибку:
ResourceType *newResource = (ResourceType*)allocator.alloc();
ResourceType t;
*newResource = t; //error is thrown from here
Когда я использую это для sf::Texture
он работает правильно, эта ошибка возникает только тогда, когда я использую sf::Font
Для sf :: Font размер класса составляет 76 байт, а выравнивание - 4 байта, мой распределитель выполняет это и выделяет ему блок из 76 байтов с выравниванием по 4 байт, Я не выясните, как решить эту ошибку.
Редактировать: Я пробовал его для sf::SoundBuffer
и он бросает подобную ошибку.
бассейна инициализация Allocator:
bool PoolAllocator::init(const unsigned int & numBlocks, const unsigned int & blockSize, const int&alignment)
{
if (mpMemoryBlock)
{
return false;
}
// assert(alignment & (alignment - 1) == 0);
auto expandedBlockSize = alignUp(blockSize, alignment);
mBlockSize = expandedBlockSize;
mAlignment = alignment;
mBlocks = numBlocks;
mpMemoryBlock = malloc((expandedBlockSize * numBlocks) + alignment);
if (!mpMemoryBlock)
{
return false;
}
auto currentBlock = alignUp((uintptr_t)mpMemoryBlock, alignment);
nextFreeBlock = currentBlock;
auto nextBlock = currentBlock;
mpActualBlock = (void*)currentBlock;
for (int i = 0; i < static_cast<int>(numBlocks); i++)
{
nextBlock = currentBlock + expandedBlockSize;
auto alignedForNextPointerStorage = alignUp(currentBlock, sizeof(uintptr_t));
*((uintptr_t*)alignedForNextPointerStorage) = nextBlock;
currentBlock = nextBlock;
}
auto alignedForNextPointerStorage = alignUp(currentBlock, sizeof(uintptr_t));
*((uintptr_t*)alignedForNextPointerStorage) = 0;
return true;
}
распределение Бассейна Allocator:
void * PoolAllocator::alloc()
{
if (*((uintptr_t*)nextFreeBlock) == 0)
{
return nullptr;
}
void *result = (void*)nextFreeBlock;
nextFreeBlock = *((uintptr_t*)alignUp(nextFreeBlock, sizeof(uintptr_t)));
return result;
}
бассейна Allocator открепление:
void PoolAllocator::dealloc(void* address)
{
auto nextPointer = alignUp((uintptr_t)address, sizeof(uintptr_t));
if ((alignUp((uintptr_t)address, mAlignment) == (uintptr_t)address) && (mpActualBlock <= address) && !((uintptr_t)address >= ((uintptr_t)mpActualBlock + (mBlocks * mBlockSize))))
{
*(uintptr_t*)nextPointer = nextFreeBlock;
nextFreeBlock = nextPointer;
}
else
{
throw std::runtime_error("Illegal deallocation of memory address : " + (uintptr_t)address);
}
}
Вы можете показать свой класс? –
Как вы на самом деле инициализируете эти экземпляры? Похоже на то, что вы пропускаете конструктор SFML для 'sf :: Font', просто отбрасывая свою память. Многие конструкторы SFML нетривиальны и поэтому вы не можете просто пропустить их. – Mario
@Mario Вот почему я создаю ResourceType t и копирую его в выделенном блоке, который должен скопировать построенный по умолчанию объект t в newResource правильно? –