2017-06-24 23 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このアロケータ::ベクトル、gccの上を使用して。だから私が知っている限り、奇妙なリバインドのものが起こっている

+0

アロケータはコピー可能でなければなりません。ステートフルなアロケータへの典型的なアプローチは、共有するオブジェクトに転送する軽量のコピー可能なプロキシを持ち、状態を維持し、実際の作業を行うことです。 –

+0

これはコピー可能ではありませんか?このアロケータのデフォルトのコピーコンストラクタは状態(ブロックのベクトル)をコピーし、次に2つの同一のアロケータを持つべきです。私のアロケータを使用しているベクトルが「古い」コピーを使用しているように見えますか? –

+0

はい、アロケータはコピー可能ですが、コピーは状態を共有しません。それぞれにはブロックの独立したリストがあり、他のブロックによって割り当てられたブロックについてはわかりません。ところで、あなたの 'operator =='実装を指摘したので、クラスは[allocator requirements](http://en.cppreference.com/w/cpp/concept/Allocator)に違反します:アロケータのコピーは、元のものと同等ですが、あなたのものはそうではありません。 ( 'operator!='もありません)。したがって、最初はアロケータクラスでさえありません。 –

答えて

0

@Igorが述べたように、アロケータはコピー可能でなければなりません。重要なのは、それらがコピーされた後であっても、コピー間で状態を共有する必要があることです。この場合、修正は簡単でした。私は、ブロックベクトルをshared_ptrを提案したようにしてコピーしました。そのコピーは、同じベクトルをすべての更新が同じベクトルを発生させるため、すべてが同じものを指しています。

関連する問題