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

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

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

4

5 に答える 5

24

私は最近これを自分でやりたいと思っていましたが、次のコードが明らかになりました。

Chronium の stack_container.h

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

これを行うことの有用性と妥当性に疑問を持っている人は、次のことを考慮してください。

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

一部の人々は、スタックベースの割り当てを使用する文字列はstd::string、あたかもこれが何らかの形でその有用性を損なうかのようにではないとコメントしています。確かに、この 2 つを同じ意味で使用することはできませstackstringstd::string。しかし(正しく行えば)、 、 などで現在使用しているのと同じすべてのメンバー関数を で使用でき、引き続き 正常にstackstring動作するため、多くの を使用できます。 STL アルゴリズム。確かに、これは厳密な意味ではありませんが、実用的な意味では「文字列」であり、非常に便利です。std::stringfind_first_of()append()begin()end()std::string

于 2009-04-24T02:37:26.673 に答える
12

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

したがって、原則std::basic_stringとして、スタック上のメモリを使用するアロケータで のインスタンス化を使用できますが、std::string. 特に、ランタイム ポリモーフィズムが得られず、結果のオブジェクトをstd::string.

于 2009-04-23T23:32:07.710 に答える
4

できません。を除外する...

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

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

おそらく、メモリ管理にallocaを使用する Allocator クラスを定義できます。これは、Allocator 自体と、basic_stringそれを直接または間接的に呼び出すメソッドが all である場合にのみ機能しますinlinebasic_stringこのアロケータで作成されたオブジェクトは ではありませんstd::string(ほとんど) そのように動作します。ただし、これは限られた利益のためのかなりの量の作業になります。具体的には、このクラスを使用して関数から値を返すことは、キャリアを制限する動きになります。

なぜあなたや他の誰かがこれをしたいのか分かりません。

于 2009-04-23T23:36:40.633 に答える
0

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

于 2009-04-23T23:23:27.687 に答える
-3
  • std :: stringは、常にnew/deleteを使用して内部ストレージを管理します。
  • 質問にglibcの文字列実装が含まれている理由がわかりません。c ++標準ライブラリの文字列実装は、 glibcとは何の関係もありません。
  • 文字列をスタックに格納する唯一の方法は、スタックでC char配列を使用することです(Shhnapが概説したように)。しかし、それはおそらくあなたがとにかく望むものではありません:-)
于 2009-04-23T23:23:57.357 に答える