yohhoyの日記

技術的メモをしていきたい日記

C++標準文字列:c_str, data, operator[]

C++標準ライブラリ文字列クラステンプレーstd::basic_stringメンバ関数c_str, dataおよびoperator[]の仕様ついてメモ。

basic_string の data と c_str の挙動の変更
C++03 では c_str メンバ関数の返す文字列は null 終端されていることが保証されていましたが、data メンバ関数が返す値は null 終端されている保証はありませんでした。
C++11 では、c_str も data も同じ仕様になり、両方とも null 終端されていることが保証されるようになりました。
また、C++03 では c_str, data の計算量を規定していませんでしたが、C++11 では定数時間であることが保証されることになりました。

http://d.hatena.ne.jp/melpon/20111213/1323705670

比較表

C++03 C++11
s.c_str() ヌル終端文字列{'a', 'b', '\0'}を指すポインタ ヌル終端文字列{'a', 'b', '\0'}を指すポインタ
e.c_str() ヌル終端文字列{'\0'}を指すポインタ ヌル終端文字列{'\0'}を指すポインタ
s.data() データ領域{'a', 'b'}を指すポインタ
(ヌル終端文字'\0'を含まない*1
ヌル終端文字列{'a', 'b', '\0'}を指すポインタ
s.c_str()と同一)
e.data() データ領域{'\0'}を指すポインタ
ヌル終端文字列{'\0'}を指すポインタ
e.c_str()と同一)
s[0] 'a'をもつ領域への参照 'a'をもつ領域への参照
s[2] 未定義動作 '\0'をもつ領域への参照
ただしs[2]='c';は未定義動作
cs[0] 'a' 'a'
cs[2] '\0' '\0'
c_str/data呼出 同文字列オブジェクト中の要素を指す参照/ポインタ/イテレータを無効化する可能性がある 無効化しない

表中のs"ab"に対応する文字列オブジェクトを、eは空文字列オブジェクト(e.size() == 0)を表し、cssに対応するconstオブジェクトとする。

C++03

C++03 21.3/p5, 21.3.4/p1, 21.3.6/p1-4より一部引用。

5 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:

  • Calling data() and c_str() member functions.
  • Calling non-const member functions, except operator[](), at(), begin(), rbegin(), end(), and rend().

const_reference operator(size_type pos) const;
reference operator
(size_type pos);
1 Returns: If pos < size(), returns *(begin() + pos). Otherwise, if pos == size(), the const version returns charT(). Otherwise, the behavior is undefined.

const charT* c_str() const;
1 Returns: A pointer to the initial element of an array of length size() + 1 whose first size() elements equal the corresponding elements of the string controlled by *this and whose last element is a null character specified by charT().
2 Requires: The program shall not alter any of the values stored in the array. Nor shall the program treat the returned value as a valid pointer value after any subsequent call to a non-const member function of the class basic_string that designates the same object as this.

const charT* data() const;
3 Returns: If size() is nonzero, the member returns a pointer to the initial element of an array whose first size() elements equal the corresponding elements of the string controlled by *this. If size() is zero, the member returns a non-null pointer that is copyable and can have zero added to it.
4 Requires: The program shall not alter any of the values stored in the character array. Nor shall the program treat the returned value as a valid pointer value after any subsequent call to a non-const member function of basic_string that designates the same object as this.

C++11

N3337 21.4.1/p6, 21.4.5/p1-4, 21.4.7.1/p1-3より一部引用。

6 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:

  • Calling non-const member functions, except operator[], at, front, back, begin, rbegin, end, and rend.

const_reference operator(size_type pos) const;
reference operator
(size_type pos);
1 Requires: pos <= size().
2 Returns: *(begin() + pos) if pos < size(). Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object leads to undefined behavior.
3 Throws: Nothing.
4 Complexity: constant time.

const charT* c_str() const noexcept;
const charT* data() const noexcept;
1 Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
2 Complexity: constant time.
3 Requires: The program shall not alter any of the values stored in the character array.

C++11におけるstd::basic_string内部の文字列表現は、連続したメモリ領域に配置されることが保証される*2

関連URL

*1:C++03規格上は「ヌル終端文字を含むことを要求しない」だけなので、処理系によってはヌル終端文字を含むデータ領域へのポインタを返すかもしれない。

*2:"The char-like objects in a basic_string object shall be stored contiguously."(N3337 21.4.1/p5)