私は最近、アロケータの複数のインスタンス間で共有されるメモリプールに基づいてカスタムアロケータを開発しています。STLコンテナ、SBOとカスタムアロケータの競合
意図は、アロケータはSTLおよび標準Cと互換性があるということでした++などなど
ベクトル、両端キュー、マップ、文字列としてベースのコンテナは、しかし、特に何かが私にいくつかの混乱を引き起こしました。 std :: vector,std :: stringのようなコンテナのさまざまな実装では、小さなバッファの最適化 - 小さな初期メモリ要件のためのスタックベースの割り当てを使用します。たとえば、MSVC9.1については
はのbasic_stringクラスに次のメンバーがあります。
union _Bxty
{ // storage for small buffer or pointer to larger one
_Elem _Buf[_BUF_SIZE];
_Elem *_Ptr;
char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;
は、私がこのような容器をインスタンス化する際に1だけに実装 を丸めると常に提供アロケータを使用する方法を見ることができないが SBOは使用しません。 カスタムアロケータを実装する意図の1つが、共有メモリの量が のコンテキストで使用できるようになったためです。例えば
私はSTD二 インスタンス::多分より小さいかSBO上部 限界に等しいメモリの共通ブロック を共有するプロセスごと文字列いずれかを持つことができる状況を持っていると思います。
おそらく関連:May std::vector make use of small buffer optimization?
typedef std::vector<int,mysharedmemallocator> shmvtype;
shmvtype v(2,0); //<-- if SBO then error as memory is allocated on
//stack not via the allocator
v[1] = 1234; //<-- if SBO then error as wrong piece of memory
// is being modified.
はオーバー何人かの人々のために物事を複雑に思えるとして共有メモリに基づいていない別の例を見てみましょう。私は私のstd :: basic_stringやstd :: vectorなどを特化したいとします。アロケータは、0xABで割り当てられたメモリを塗りつぶすアロケータを持っています。
この新しいアロケータに特化しているがSBOも使用するコンテナは、0xABパターンでいっぱいになったSBOベースのメモリを持ちません。例えばだから:カスタムアロケータを実装する意向の
typedef std::basic_string<char,myfillmemallocator> stype
stype s;
s.resize(2);
assert(s[0] == 0xAB); // if SBO this will fail.
コメントありがとうございますが、ちょうど1つの質問ですが、共有メモリを割り当てるアロケータを持つことはできませんし、オフセットポインタのコンセプトを使ってメモリをエイリアスすることもできます - これは通常どおりに行われます(boost.interprocess)確かに私はそれができない理由を理解しています。 –
@セミナー:その文字列をコピーするとどうなりますか?その文字列に文字を挿入すると、再割り当てが発生する可能性があります。これらの操作のセマンティクスがどのようなものであるべきかは明確ではありませんが、セマンティクスが何であっても、実装自体が知る必要があるセマンティクスです。つまり、特定の方法で動作する特定のコンテナ実装が必要です。 –
共有文字列から別の文字列へのコピーは共通のコピーですが、ターゲット文字列は共有メモリを持つことは期待できません。これは他の方法でも同じです。通常のstd :: stringからコピーします特別なアロケータによって提供される共有メモリに格納されます - これは、Resize/Append et alに関する質問 –