2009-10-20 19 views
5

なぜ私は次のステートメントがstd::string s与えられていないことに気づいた。なぜstd :: string :: max_size()== std :: string :: allocator :: max_size()

s.max_size() == s.get_allocator().max_size(); 

私は、これは面白い、デフォルトstd::stringsize_type(-1)の理論的限界があるstd::allocator<char>使用する見つける(はい私は、私は2の補数を仮定している知っているが、それは、実際の質問には無関係です)。私は実際的な制限がこれよりもはるかに少ないことを知っています。典型的な32ビットx86システムでは、カーネルは2GB(おそらく1GB)のアドレス空間を占有し、実際の上限はずっと小さくなります。

とにかく、GNU libstdC++のstd::basic_string<>::max_size()は、使用しているアロケータの内容にかかわらず同じ値を返すようです(1073741820など)。

質問が残っているので、なぜstd::basic_string<>::max_size()get_allocator().max_size()を返しますか?これが仮説上の上限だと私には思われます。割り当てが不足すると、std::bad_allocが投げられますので、試してみてはいかがですか?

これは他の何よりも好奇心が強いです。なぜこの2つの実装が少なくともこの1つの実装では別々に定義されているのか不思議でした。

+0

「そして、もし割り当てが短くなる、それはちょうどstd :: bad_allocを投げるので、なぜ試してみませんか? "私はあなたのためにそれに答えることができます。大規模な文字列を処理し、大きな文字列に分割する必要があるかもしれません。実際にmax_sizeが何を報告しているかに依存できない場合は、アドホックな制限に頼らざるを得ません。 – GManNickG

+0

私はあなたの意見を見ますが、私は同意しません。現実には、文字列サイズ<= 'max_size()'は、外部変数(ヒープでどれくらいの量が利用可能か)に依存しているため、失敗する可能性があると仮定する必要があります。 –

+0

合意。私の唯一のポイントは、少なくとも正確なものにしようとするべきです。実用的な数字に最高の希望を与えてください。 :)しかし、難しい質問。 – GManNickG

答えて

10

Microsoft Connectさんがあなたの質問に関連したバグを報告しました。

私たちは、標準の解釈に従って、max_size()の意図された目的がはっきりしていないことを解決しました。 Allocatorのmax_size()は、 "X :: allocate()"(C++ 03 20.1.5 [lib.allocator.requirements] /表32)に有意義に渡すことができる最大の値ですが、container max_size (23.1 [lib.container.requirements] /表65)。 max_size()コンテナがアロケータmax_size()から導出されるべきかどうか、またはどのようにコンテナmax_size私たちの長年にわたる実装では、allocator max_size()から直接コンテナmax_size()を導出し、オーバーフローチェックなどのためにこの値を使用しました。あなたのような本基準の他の解釈も可能ですが、私たちにはあいまいではありません。スタンダードの言葉は、ここでの説明から明らかに利益を得ることができます。私たちは現在の実装を変更しない限り、(1)他の顧客は現在の動作に依存している可能性があり、(2)max_size()は基本的に何も購入しません。アロケータ(コンテナなど)を消費するものは、allocate()がいつ失敗するかを予測するためにallocator max_size()を使うことができますが、単にallocate()を呼び出す方が良いでしょう。コンテナを消費するものは、size()の大きさを保証するためにcontainer max_size()を使用できますが、size_typeの範囲はより簡単です。

さらにhereコアの問題#197が見つかりました。委員会はスタンダードの言葉の改善要請を検討したが、それは却下された。

あなたの質問に対する答えは「なぜ?

4

私は完全にはわかりませんが、私が知る限り、std::basic_stringは現在の標準では文字列を連続メモリに格納することに限定されていません。例えば、それをいくつかのチャンクに格納することができます。そのような各チャンクはstd::allocator::max_size()に制限されますが、合計はそれよりも大きくなることがあります。

STLコンテナの場合もそうです。結局のところ、std::basic_stringはコンテナです。

+0

誰もこの方法で実装しない人はいないでしょうが、次の標準ではそれが許されないかもしれません(完全にはわかっていないかもしれません)。そしてOPは、アロケータが許す範囲よりもかなり小さい* – UncleBens

1

GCCの実装では、どのように計算するのかを説明していますmax_size(1つのブロックとして割り当てられた内部ハウスキーピングオブジェクトのサイズを引く必要があります)その文字列を使って)、そしてmax_size()がその4分の1を返すと付け加えます。論理的根拠はありませんので、おそらく安全マージンでしょうか?(これはロープクラスも提供するはずです。 )allocator.max_size()より1少ないVC++ max_size()リターンで

- 。おそらく、NULL文字を終端するために考慮するため

関連する問題