2016-12-11 5 views
0

SSOの説明では、小さな文字列がヒープに割り当てられています:OKですが、コンテナ内で構築された場合、コンテナが関数と戻りで作成され、関数スタックは古くなるため、C++小文字の最適化(SSO)はどのようにコンテナで動作しますか?

SSOはSTLコンテナでは動作しないと思いますか?

+0

あります。小さな文字列はstd :: stringオブジェクトに直接格納されます。文字列が許可されたサイズよりも大きくなるように展開されると、ヒープに再割り当てされます(std :: stringからのポインタ)。 –

答えて

2

"小さい文字列"と "大きな文字列"の違いは、スタックまたはヒープに格納する違いではありません。代わりに、相違のレベル間接指示です。それは何を意味

std::stringオブジェクトが(ほとんど)任意の長さであり得る実際の文字列データへのポインタを保持することが可能であるが、全ての間接的なダイナミックメモリの欠点有する - 割り当て、割り当て解除、キャッシュミス等

また、std::stringでは、割り当てられている場所のどこでも、std::stringオブジェクトのすぐ内側に小さな文字列を格納できます。オブジェクトがヒープ上のいくつかのコンテナにある場合、その文字列はどこにあるのでしょうか?大きな文字列のように別の間接指定は必要ありません。

2

vectorとを例にしてみましょう。

  1. 通常 "のように見える" ものをvector見るためにmy answer to 'c++ Vector, what happens whenever it expands/reallocate on stack?'を参照してください。

  2. stringvectorの中に格納すると、すべてstringインスタンスがヒープになります。自体は

    • は、オブジェクトインスタンス(SSO)または
    • 内の文字列データ自体を含むことができるいずれか

    • 列インスタンスは、コンテンツを格納するためにヒープ上にメモリを割り当てます。

  3. クラスがそのデータを格納するクラスには関係ありません。自分でデータを管理するオブジェクトだけを保持します。

SSOは、容器内にstringを格納することに影響しません。

PS:関数からスタックオブジェクトを返すことはもちろん可能です。関数スタックは「範囲外」になりますが、戻り値は保持されます。それ以外の場合はintを返すことさえできませんでした。

SSOはstringコンテンツがどんなスタック上にないことを意味するものではありません。これは、小さな文字列のデータがstringインスタンス内に格納されていることを意味します。インスタンスがスタック上にある場合、データはスタック上にあります。オブジェクトがヒープ上にある場合、データはヒープ上にもあります。

1

"小さいオブジェクトの最適化"を持ったベクトルのようなクラスを書くことはできますが、オブジェクトが小さく、内部的に(コンテナオブジェクト自体の内部に)オブジェクトを格納しない場合はヒープに格納します(std::vectorのようになりました)。

ただし、これは、標準ライブラリのコンテナには、要件が課せられているため、現在のところ不可能です。具体的には、[container.requirements.general]/9は、

のようになります。スワップは、スワップ後に他のコンテナ内の同じ要素を参照する前に、1つのコンテナ内の要素を参照します。

これは、小さなオブジェクトの最適化では難しく、その要件はbasic_stringには当てはまりません。

関連する問題