2013-07-01 4 views
11

文字列クラスによってメンテナンスされている配列の開始アドレスにアクセスしたいとします。文字列クラスのc_str()メソッドは何を返しますか?

​​
  1. (文字列クラスによって維持される)、配列のアドレスを指すポインタですか?または文字列クラスは、ダイナミックメモリから新しい配列を作成し、既存の文字列をコピーしてそのアドレスを返しますか?

  2. これが正しい方法でない場合は、文字列クラスによって維持されている配列の開始アドレスにアクセスする方法は?

+9

*なぜ*このアドレスをお探しですか?ストリングに何をしようとしていますか? – trojanfoe

+1

C++ 11の回答かC++ 03の回答をお探しですか?正解はこれに依存します。それ以上の仕様がなければ、私はさらにC++ 11と仮定します。 –

+0

あなたはあなたの質問によく答えることができるかもしれません。あなたは数分前にここにいました。 –

答えて

23

C++ 11標準明示的.c_str()(ならびに.data()新しい)はstd::stringで使用される内部バッファへのポインタを返すことを述べています。

にはchar *が返さ言っ.c_str()かもしれ結果を経由してポインタを取得した後のstd ::文字列の任意の変更は無効になりました(つまり - std::stringは内部スペースを再割り当てしなければならなかった場合)。

以前のC++標準では、実装は何かを返すことができます。しかし、標準ではユーザーが結果の割り当てを解除する必要はないので、新しく割り当てられたものを返す実装は見たことがありません。少なくともGNU gccとMSVC++のSTL文字列は内部でゼロ終了文字配列で、c_str()によって返されます。

したがって、C++の任意のバージョンの実装では、.c_str()が内部バッファを返すと想定するのが安全です(通常のC++では注意が必要です)。

言い換えれば、.c_str()の値を決して保持してはいけません。あなたが100%確実でない場合は、いつでもサイズを変更しません(constの場合を除きます)。

P.S.ところで、決して​​を行うべきではありません。それはconst char *だとあなたは上記の - 一部の他のオブジェクトまたはの内部状態を破損しているメモリを上書きする可能性がありますので、部分的に内容を変更しないものとします。それを見ましたが、ちょっと - それは封筒です!)

+0

これはまさに私が期待していた答えです。 –

+0

...もちろん*定数文字列*を変更することは、プロセス内に存在する場所(つまり、おそらく読み取り専用のメモリページ)のために悲惨な状況になります。 – trojanfoe

+1

@Andrian Nordまた、サイズ変更の確率が0の場合は??新しい文字列オブジェクトを作成し、resize(512)メソッドを使用しました。 512は私のアプリケーションで可能な文字列の最大長です。今私はc_str()を使用してアドレスを取得し、オブジェクトのappend()メソッドを使用して、それは大丈夫でしょうか? –

1

あなたはchar *address = &str[0];により、文字列の先頭のアドレスを取得することができます。文字列をC文字列表現に変換する必要はありません。

+2

'const char'、確かに? –

+0

私はそれが正しく動作することは保証されているとは思わない。 – davmac

+0

@PeterWoodいいえ、必須ではありません。 –

0

C++ 11では、ポインタは、現在の文字列オブジェクトがその値に一致する文字を格納するために現在使用されている内部配列を指しています。

詳細については、http://www.cplusplus.com/reference/string/string/c_str/を参照してください。

+0

@trojanfoe私が答えに載せたリンクはこう書いています: "string :: dataとstring :: c_strの両方は同義語で、同じ値を返します。" –

+0

@trojanfoe C++での動作は異なる場合があります。少なくともhttp://stackoverflow.com/a/7554172/533480はそう言った。 –

+0

合意。私のコミットを削除します。 – trojanfoe

4

NOTEは:私の答えはpre-C++11ための唯一の正しいです。 C++ 11では、thisが正しい答えです。


  1. それはヌル終端とC文字列を返します。 std::string自体はヌルで終端されていないので、実装ではconst charの新しく割り当てられた配列を返すことができます(おそらくそうなります)。 std::stringの作成が範囲外になるか、またはそれが変更されている場合は、c_str()6返された文字列は無効になります。

  2. data()はデータを返しますが、NULLで終了する文字列ではないことに注意してください。どちらの場合

、あなたは両方data()c_str()リターンポインタはconst charに、そのデータを微調整することになって、そしてあなたが本当にいけないされています。

たとえば、std::stringなどは参照カウント文字列にすることができます(これはもう一般的ではありません)。または、データにファンキーなインデックススキームを使用することもできます。

1

文字列の中に実際に "データ"を入れる場合は、string::data()が探している機能です。

ただし、c_str()のように、データへのポインタはconstです。このデータを変更する必要はありません。

関連する問題