2

特定のプラットフォームの文字列の長さ(C ++)の上限をどのように修正できるのか疑問に思いました。

私は多くのライブラリを精査しました、そしてそれらのほとんどはそれを恣意的に定義します。GNU C ++ STL(実験的なC ++ 0x機能を備えたもの)にはかなりの定義があります:

size_t npos = size_t(-1); /*!< The maximum value that can be stored in a variable of type size_t */
size_t _S_max_len = ((npos - sizeof(_Rep_base))/sizeof(_CharT) - 1) / 4; /*!< Where _CharT is a template parameter; _Rep_base is a structure which encapsulates the allocated memory */

これが私が式を理解する方法です:

  • size_tタイプは、文字列に割り当てられたユニットの数を保持する必要があります(各ユニットはタイプ_CharTです)
  • 理論的には、size_t型の変数がとることができる最大値は、割り当てられる可能性のある1バイト(つまり、char型)のユニットの総数です。
  • したがって、前の値から割り当てられたメモリ(_Rep_base)を追跡するために必要なオーバーヘッドを差し引いた値が、文字列内のユニットの最大数になります。_CharTは1バイト以上を必要とする可能性があるため、この値をsizeof(_CharT)で除算します
  • 前の値から1を引いて、終了文字を考慮します
  • 最後に、それは4による分割を残します。理由はまったくわかりません。

説明のためにたくさんの場所を調べましたが、満足のいく場所がどこにも見つかりませんでした(そのため、私はそれを補うために努力してきました!間違っている場合は訂正してください!!)。

4

4 に答える 4

2

GCC 4.3.4 の basic_string.h のコメントには次のように記載されています。

    // The maximum number of individual char_type elements of an
    // individual string is determined by _S_max_size. This is the
    // value that will be returned by max_size().  (Whereas npos
    // is the maximum number of bytes the allocator can allocate.)
    // If one was to divvy up the theoretical largest size string,
    // with a terminating character and m _CharT elements, it'd
    // look like this:
    // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
    // Solving for m:
    // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
    // In addition, this implementation quarters this amount.

特に、最後の行に注意してください。「さらに、この実装はこの金額を四分の一にします。」 これは、実際には 4 による除算が完全に恣意的であることを意味します。

basic_string.hのチェックイン ログで詳細を見つけようとしましたが、それは 2000 年 10 月 5 日までさかのぼるだけで、このコメントはそのリビジョンに示されているようにすでに存在していました。ファイルが現在の場所に移動される前に、ファイルがソース ツリーのどこにあったかを知ることができます。

于 2010-04-06T18:33:30.850 に答える
0

を含む小さなラッパークラスを作成できますstd::string。気になるインターフェース機能を公開します。関数呼び出しによって文字列が目的の最大長を超えて増加する場合は、例外をスローするか、エラーをトリガーする可能性があります。

これは、標準ライブラリの実装を解読するという混乱を掘り下げることなく、目標を達成する(文字列の最大長を固定する)方法として意図されています。

于 2010-03-19T17:54:14.433 に答える
0

実行時にチェックしてもかまわない場合std::string::max_sizeは、文字列の可能な最大長を返す を呼び出すことができます。これは、その結果の理由を教えてくれません (そして/4、GNU コードの目的が何なのか、私にはわかりません) が、少なくとも、作業する明確な何かが得られます。

ただし、これは静的関数ではないため、すべての文字列の正しい値を決定するには、少し注意が必要な場合や、システム固有のコードが必要になる場合があります。(たとえば、VC++ 文字列は、この情報についてはそのアロケーターに従うように見えます。つまり、異なるアロケーターを使用している場合、異なる文字列は異なる最大サイズを持つ可能性があることを意味します。)

于 2010-03-19T18:16:50.670 に答える
0

実際の制限は、絶対制限よりもはるかに小さい可能性があります。たとえば、メモリ割り当ては失敗します。実際の限界を前もって知ることはできません。

于 2010-03-19T18:20:50.850 に答える