C ++有状态分配器解除分配问题

时间:2017-06-24 17:22:25

标签: c++11 memory-management allocator

这个问题是我对标准如何使用我的自定义分配器的误解。我有一个有状态的分配器,它保存一个已分配块的向量。在解除分配期间分配和搜索时,该向量被推入。

从我的调试中看来,我的对象的不同实例(这个*不同)在解除分配时被调用。一个例子可能是调用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。所以据我所知,没有任何奇怪的重新发布的东西正在进行中

1 个答案:

答案 0 :(得分:0)

正如@Igor所提到的,分配器必须是可复制的。重要的是,尽管他们必须在副本之间共享它们的状态,即使它们被复制之后也是如此。在这种情况下,修复很容易,我按照建议使块矢量为shared_ptr,然后在复制时,对该向量的所有更新都发生在同一个向量中,因为它们都指向同一个东西。