std :: setはオブジェクトを連続してメモリに格納しますか?


16

std::setような連続したメモリにオブジェクトを保存しますstd::vectorか?

これをWeb上で見つけることはできませんでした。cppreferenceはメモリ割り当ての詳細について言及していません。しかし、なぜそれが連続したメモリを使用できなかったのかわからないので、私の質問です。


5
set::insert要件の読み取り:en.cppreference.com/w/cpp/container/set/insert "...イテレータまたは参照は無効化されていません..."なので、必要なときに再割り当てできませんstd::vector
Richard Critten

パフォーマンス:(ハッシュ関数に応じて)ユースケースを測定する必要があります。channel9.msdn.com / Events / Build / 2014 / 2-661を45:48から参照
Richard Critten

4
boost :: flat_setも参照してください。
Caleth

1
「セットが反復されると、オブジェクトは連続したメモリロケーションに格納されます」または「すべてのオブジェクトは1つの大きなメモリチャンクに格納されます(ただし、任意の順序で)」のように「連続」することを意味しますか?
パブロH

1
一般に、「コンテナーAはコンテナーBと同じですか」と質問した場合、答えは「いいえ」です。そうでない場合、コンテナーAのみになります(コンテナーBを作成する目的は何ですか?)。もちろん、これはコンテナアダプタには当てはまりませんstd::setが、ここでは重要なことではありません。
オービットでのライトネスレース

回答:


25

std :: setはstd :: vectorのような連続したメモリにオブジェクトを格納しますか?

それが保証するものではありません。また、実際には、コンテナの要件のためにできません。したがって、いいえ、それは連続したメモリにオブジェクトを格納しません。

連続メモリを使用できなかった理由がわかりません

セットの要素への参照は、それへの挿入時および消去時に有効のままである必要があります(消去された要素への参照を除く)。この要件は、隣接するメモリと互換性がありません。

私の知る限り、バランスのとれた検索ツリーは、を実装できる唯一のデータ構造ですstd::set


OPが意味する場合に備えて、大きな連続したチャンクからツリーノードのスペースを切り分けることができます。(ただし、インプレースのreallocが失敗した場合、または(C ++の一般的な)アロケーターがそのようなreallocをサポートしない場合に備えて、イテレーターの無効化insertは、すべてのノードを新しい大きなブロックにコピーして1つのブロックのみに制限することを除外していません。)
Peter Cordes

15

特定の制約により、std::set連続したメモリを使用できなくなりますが、明示的に除外されていません。

たとえば、set::insertは対数的に複雑vector::insertですが、エントリをシャッフルするには線形的な複雑さが必要です。また、set::insertイテレータを無効にしません。両方の要件は、連続メモリでは実現できません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.