好的,我在使用boost::fast_pool_allocator
时遇到了一些问题。
我的代码正在为fast_pool_allocator::allocate(1)
的前几次调用工作,
但随后失败了以下消息:
Engine.exe中0x000000013fd0fe2d处的未处理异常:0xC00000005: 访问冲突读取位置0x0000000000ffffff
调用堆栈:
Engine.exe!boost::simple_segregated_storage<unsigned __int64>::malloc() Line 104
Engine.exe!boost::pool<boost::default_user_allocator_new_delete>::malloc() Line 223
Engine.exe!boost::singleton_pool<boost::fast_pool_allocator_tag,128,boost::default_user_allocator_new_delete,boost::details::pool::win32_mutex,32>::malloc() Line 59
Engine.exe!boost::fast_pool_allocator<EventDataSize,boost::default_user_allocator_new_delete,boost::details::pool::win32_mutex,32>::allocate(const unsigned __int64 n) Line 229
Engine.exe!IEventData::operator new(unsigned __int64 size) Line 46
etc...
有问题的提升代码行似乎正确,分配器存储机制即将返回下一个空闲块,并将其从 免费块列表
void * malloc()
{
void * const ret = first;
// Increment the "first" pointer to point to the next chunk
first = nextof(first); // <--- This is the line that is failing.
return ret;
}
我的代码如下所示:
class EventDataSize
{
private:
U8 dummyField[128];
};
class IEventData
{
public:
void* operator new(size_t size)
{
void* ptr = boost::fast_pool_allocator<EventDataSize>::allocate(1);
if (!ptr)
throw std::bad_alloc();
return ptr;
}
void operator delete(void* ptr)
{
boost::fast_pool_allocator<EventDataSize>::deallocate((EventDataSize*)ptr, 1);
}
// etc...
}
正如您所看到的,我正在尝试将此EventDataSize
类用作伪,因此任何继承自IEventData
的类将被分配相同的大小(例如128个字节),允许池分配器与继承一起愉快地工作。
我在其他地方使用完全相同的模式来实现new new与其他基类,并且它们似乎没有遇到同样的问题。
奇怪的是,如果我改变EventDataSize::dummyField
的数组大小,问题就会消失(至少,它还没有出现),但我对这种不合标准的解决方案感到不舒服...我想要知道为什么这个分配器正在做它正在做的事情,我做错了什么,以及我如何能够优雅地修复它!
答案 0 :(得分:3)
我意识到,因为我有另一个基类IControl,使用相同的模式,并使用自己的ControlSize虚拟(也是128字节),两个fast_pool_allocators都使用相同的池对象。
然而,我的一个IControl子类大于128字节。因此,分配没有问题,但随后覆盖池链接的免费块列表。
基本上,这正是Oo Tiib所讨论的问题,但转移到了稍微不同的代码部分。
我在Oo Tiib展示和bish-bash-bosh的两个地方修复了代码,它就像一个魅力!
答案 1 :(得分:2)
始终测试你的理论(无论它们是什么)。你似乎有一个理论,128字节对任何IEventData都足够好,所以你可以忽略它的大小?来吧测试一下:
void* operator new(size_t size)
{
if ( size > sizeof( EventDataSize ) )
{
throw std::runtime_error("crappy idea, pal");
}
void* ptr = boost::fast_pool_allocator<EventDataSize>::allocate(1);
if (!ptr)
throw std::bad_alloc();
return ptr;
}
对我来说,感觉事件数据可能超过128个字节,所以它搞砸了池分配器池中的东西。