这个问题是我对标准如何使用我的自定义分配器的误解。我有一个有状态的分配器,它保存一个已分配块的向量。在解除分配期间分配和搜索时,该向量被推入。
从我的调试中看来,我的对象的不同实例(这个*不同)在解除分配时被调用。一个例子可能是调用MyAllocator(this * = 1)来分配20个字节,然后一段时间后调用MyAllocator(this * = 2)来解除分配之前分配的20个字节。显然,MyAllocator中的向量(this * = 2)不包含另一个分配器分配的20字节块,因此无法解除分配。我的理解是C ++ 11允许有状态分配器,发生了什么以及如何解决这个问题?
我已将我的operator ==设置为仅在此==& rhs
时返回true伪码:
template<typename T>
class MyAllocator
{
ptr allocate(int n)
{
...make a block of size sizeof(T) * n
blocks.push_back(block);
return (ptr)block.start;
}
deallocate(ptr start, int n)
{
/*This fails because the the block array is not the
same and so doesn't find the block it wants*/
std::erase(std::remove_if(blocks.begin,blocks.end, []()
{
return block.start >= (uint64_t)ptr && block.end <= ((uint64_t)ptr + sizeof(T)*n);
}), blocks.end);
}
bool operator==(const MyAllocator& rhs)
{
//my attempt to make sure internal states are same
return this == &rhs;
}
private:
std::vector<MemoryBlocks> blocks;
}
我在gcc上使用这个分配器作为std :: vector。所以据我所知,没有任何奇怪的重新发布的东西正在进行中
答案 0 :(得分:0)
正如@Igor所提到的,分配器必须是可复制的。重要的是,尽管他们必须在副本之间共享它们的状态,即使它们被复制之后也是如此。在这种情况下,修复很容易,我按照建议使块矢量为shared_ptr,然后在复制时,对该向量的所有更新都发生在同一个向量中,因为它们都指向同一个东西。