2017-06-24 53 views
0

這個問題是我對標準如何使用我的自定義分配器的誤解。我有一個有狀態的分配器,保持分配塊的向量。在分配期間分配和搜索時,此向量被推入。C++狀態分配器取消分配問題

從我的調試看來,我的對象的不同實例(這*不同)正在調用解除分配。一個例子可能是調用MyAllocator(this * = 1)來分配20個字節,然後稍後調用MyAllocator(this * = 2)來取消分配前面分配的20個字節。很明顯,MyAllocator中的向量(this * = 2)不包含另一個分配器分配的20字節塊,因此無法取消分配。我的理解是,C++ 11允許有狀態的分配器,發生了什麼,我該如何解決這個問題?

我已經有我的==操作符設置爲僅返回true時,此== & RHS

僞代碼:

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; 
} 

使用這個分配器一個的std ::載體,在海灣合作委員會林。所以據我所知沒有奇怪的重新綁定的東西正在進行

+0

分配器必須是可複製的。一個有狀態分配器的典型方法是使用輕量級可複製代理來轉發它們共享的對象,該對象維護狀態並執行實際工作。 –

+0

這應該是可複製的否?這個分配器的默認拷貝構造函數應該複製狀態(塊的向量),然後我們有兩個相同的分配器。在我看來,使用我的分配器的矢量正在使用「舊」副本? –

+0

是的,你的分配器是可複製的 - 但副本不共享狀態。每個塊都有自己的獨立列表,並且不知道其他塊分配的塊。順便說一句,現在你指出你的'operator =='實現,你的類違反了[allocator requirements](http://en.cppreference.com/w/cpp/concept/Allocator):分配器的副本必須比較等於原來的,但你的沒有。 (你也缺少'operator!=')。所以它甚至不是一個分配器類。 –

回答

0

正如@Igor提到的,分配器必須是可複製的。重要的是,儘管他們必須在副本之間分享他們的狀態,甚至在副本之後也是如此。在這種情況下,修復很容易,我建議塊矢量爲shared_ptr,然後將所有更新複製到同一個矢量,因爲它們都指向相同的東西。