2

次の非常に単純なテキストの例を考えてみましょう。

#include <stdio.h>
#include <string>
int main() {
    std::string x("ugabuga");
    int i=0;
    while (x[i]) {
        ++i;
    }
    printf("%d\n",i); //should print 7
    return 0;
}

プログラムが文字列のすべての文字を反復処理し、ヌル終了文字に到達してループを破り、プログラムの最後に正しく到達することを期待します。ただし、Visual Studio 2010 でデバッグ モードでコンパイルしようとすると、「string subscript out of range」という例外が発生します。リリース モードでコンパイルすると、このプログラムは成功しますが、この動作に依存するより大きなプロジェクトがクラッシュします。おそらく、この問題が原因です。

しかし、www.cplusplus.comstd::string::operator[]で仕様を確認したところ、末尾文字列が明示的に扱われています。

pos が文字列の長さと等しい場合、関数はヌル文字 ('\0') への参照を返します。

ここでお聞きしたいのですが:

  • 私の仕様の解釈はstd::string正しいですか?または、何か不足していますか?
  • 問題が実装の VS 側にある場合、これを簡単に修正するにはどうすればよいlength()ですoperator[]か? たとえばc_str()[i]、安全に使用できますか?
  • 問題が実装の VS 側にある場合 - VS 2012 で修正されているかどうか、または将来修正される可能性があるかどうかを知っていますか?
4

1 に答える 1

7

これは、C++03 と C++11 の間で変更されたものの 1 つです。

C++03 では未定義の動作のようです:

21.3.4 basic_string 要素へのアクセス [lib.string.access]

const_reference operator[](size_type pos) const;

reference operator[](size_type pos);

1 戻り値: の場合pos < size()、 を返しますdata()[pos]。それ以外の場合pos == size()は、const version returns charT(). それ以外の場合、動作は未定義です。

一方、C++11 では問題ありません。

21.4.5 basic_string 要素へのアクセス [string.access]

const_reference operator[](size_type pos) const;

reference operator[](size_type pos);

1 必須: pos <= size()。

2 戻り値:の*(begin() + pos)場合、それ以外の場合、値を持つpos < size()タイプのオブジェクトへの参照は、参照された値を変更してはなりません。TcharT();

于 2013-08-18T13:41:57.470 に答える