glibc の文字列実装を使用してスタックに std::string を割り当てるにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/783944

質問

int main(void)
{
   std::string foo("foo");
}

私の理解では、上記のコードはデフォルトのアロケーターを使用して new を呼び出しているということです。したがって、std::string foo がスタック上に割り当てられていても、foo 内の内部バッファはヒープ上に割り当てられます。

完全にスタックに割り当てられる文字列を作成するにはどうすればよいですか?

役に立ちましたか?

解決

私は最近これを自分でやってみたかったのですが、次のコードが素晴らしいことを発見しました。

Chroniumのstack_container.h

新しいものを定義します std::allocator これにより、STL コンテナーのストレージの初期割り当てにスタックベースの割り当てが提供されます。結局、私は特定の問題を解決する別の方法を見つけたので、実際に自分でコードを使用しませんでしたが、おそらく役に立つでしょう。使用法と注意事項に関するコード内のコメントを必ずお読みください。

これを行うことの有用性と健全性に疑問を抱いている人は、次のことを考慮してください。

  • 多くの場合、文字列には妥当な最大サイズがあることが事前にわかっています。たとえば、文字列が 10 進形式の 32 ビット整数を格納する場合、そのために 11 文字を超える必要はないことがわかります。この場合、無制限のサイズまで動的に拡大できる文字列は必要ありません。
  • 多くの場合、スタックからの割り当てはヒープからの割り当てよりも高速です。
  • 文字列が頻繁に作成および破棄される場合 (一般的に使用されるユーティリティ関数のローカル変数であると仮定します)、ヒープではなくスタックから割り当てることで、ヒープ アロケータでの断片化を引き起こすチャーンを回避できます。大量のメモリを使用するアプリケーションにとって、これは大きな変革となる可能性があります。

スタックベースの割り当てを使用する文字列は、 std::string あたかもこれがその有用性を何らかの形で減少させるかのように。確かに、この 2 つを同じ意味で使用することはできないため、 stackstring を期待する関数に std::string. 。ただし、(正しく行えば) すべての同じメンバー関数を stackstring あなたが今使っているもの std::string, 、 のように find_first_of(), append(), 、など。 begin() そして end() は引き続き正常に動作するため、STL アルゴリズムの多くを使用できるようになります。もちろん、そんなことはないだろう std::string 最も厳密な意味では「文字列」ですが、実際の意味では依然として「文字列」であり、依然として非常に役立ちます。

他のヒント

問題はstd::basic_stringはアロケータのテンプレートパラメータを持っていることです。しかしstd::stringテンプレートではなく、パラメータはありません。

だから、あなたは、原則的には、スタック上のメモリを使用していますが、それはstd::basic_stringではないでしょうアロケータでstd::stringのインスタンス化を使用することができます。特に、あなたはランタイムポリモーフィズムを得ないだろう、とあなたはstd::stringを期待関数に結果のオブジェクトを渡すことができませんでした。

あなたはできません。を除外する...

std::string のインスタンス化です

std::basic_string<class CharType, 
                  class Traits=char_traits<CharType>, 
                  class Allocator=allocator<CharType> >

次の Allocator クラスを定義することも考えられます。 アロカ メモリ管理用。これは、アロケータ自体と、 basic_string それを直接的または間接的に呼び出すメソッドはすべて inline. 。あ basic_string このアロケータを使用して作成されたオブジェクトは、 なれ ある std::string, 、しかし、それは(ほとんど)そのように動作します。ただし、これは限られた利益に対してかなりの作業量となります。具体的には、このクラスを使用して関数から値を返すことは、キャリアを制限する行為となります。

わからない なぜ あなたまたは他の誰かがこれをやりたいと思うでしょう。

私はあなたがそれをやりたい理由、そのようなことをやっては、私は疑問を行うことが困難であると思われますか?完全にスタック上に何かを割り当てるには、コンパイラが事の正確なサイズが何であるかをコンパイル時に知っておく必要があります - あなたの例では、それはstd::stringメタデータのサイズだけでなく、文字列データのサイズだけでなく、知っておく必要があります自体。行うことは不可能であろうではないこと、それは少し物事を複雑にする傾向がある - これは、あなたはおそらく、あなたがそれに含めたいと思っている文字列データのサイズに応じて、異なる文字列型が必要になり、あまり柔軟ではありません。

  • std::string は常に new/delete で内部ストレージを管理します。
  • 質問になぜ次の内容が含まれるのかわかりません glibc の文字列実装. 。C++標準ライブラリの文字列実装は何の関係もありません グリブク.
  • 文字列をスタックに格納する唯一の方法は、スタック上で C char 配列を使用することです (Shnap が概説したものと同様)。しかし、それはおそらくあなたが望んでいることではありません:-)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top