SSOの説明では、小さな文字列がヒープに割り当てられています:OKですが、コンテナ内で構築された場合、コンテナが関数と戻りで作成され、関数スタックは古くなるため、C++小文字の最適化(SSO)はどのようにコンテナで動作しますか?
SSOはSTLコンテナでは動作しないと思いますか?
SSOの説明では、小さな文字列がヒープに割り当てられています:OKですが、コンテナ内で構築された場合、コンテナが関数と戻りで作成され、関数スタックは古くなるため、C++小文字の最適化(SSO)はどのようにコンテナで動作しますか?
SSOはSTLコンテナでは動作しないと思いますか?
"小さい文字列"と "大きな文字列"の違いは、スタックまたはヒープに格納する違いではありません。代わりに、相違のレベル間接指示です。それは何を意味
はstd::string
オブジェクトが(ほとんど)任意の長さであり得る実際の文字列データへのポインタを保持することが可能であるが、全ての間接的なダイナミックメモリの欠点有する - 割り当て、割り当て解除、キャッシュミス等
また、std::string
では、割り当てられている場所のどこでも、std::string
オブジェクトのすぐ内側に小さな文字列を格納できます。オブジェクトがヒープ上のいくつかのコンテナにある場合、その文字列はどこにあるのでしょうか?大きな文字列のように別の間接指定は必要ありません。
vector
とを例にしてみましょう。
通常 "のように見える" ものをvector
見るためにmy answer to 'c++ Vector, what happens whenever it expands/reallocate on stack?'を参照してください。
string
をvector
の中に格納すると、すべてstring
インスタンスがヒープになります。自体は
列インスタンスは、コンテンツを格納するためにヒープ上にメモリを割り当てます。
クラスがそのデータを格納するクラスには関係ありません。自分でデータを管理するオブジェクトだけを保持します。
SSOは、容器内にstring
を格納することに影響しません。
PS:関数からスタックオブジェクトを返すことはもちろん可能です。関数スタックは「範囲外」になりますが、戻り値は保持されます。それ以外の場合はint
を返すことさえできませんでした。
SSOはstring
コンテンツがどんなスタック上にないことを意味するものではありません。これは、小さな文字列のデータがstring
インスタンス内に格納されていることを意味します。インスタンスがスタック上にある場合、データはスタック上にあります。オブジェクトがヒープ上にある場合、データはヒープ上にもあります。
"小さいオブジェクトの最適化"を持ったベクトルのようなクラスを書くことはできますが、オブジェクトが小さく、内部的に(コンテナオブジェクト自体の内部に)オブジェクトを格納しない場合はヒープに格納します(std::vector
のようになりました)。
ただし、これは、標準ライブラリのコンテナには、要件が課せられているため、現在のところ不可能です。具体的には、[container.requirements.general]/9は、
のようになります。スワップは、スワップ後に他のコンテナ内の同じ要素を参照する前に、1つのコンテナ内の要素を参照します。
これは、小さなオブジェクトの最適化では難しく、その要件はbasic_string
には当てはまりません。
あります。小さな文字列はstd :: stringオブジェクトに直接格納されます。文字列が許可されたサイズよりも大きくなるように展開されると、ヒープに再割り当てされます(std :: stringからのポインタ)。 –