

No.5ベストアンサー
- 回答日時:
> std::string moji = str_stream.str();
> const char* c_str = moji.c_str();
この場合、moji が、最後まで生き残っていますから、moji.c_str() は有効なC文字列の先頭をポイントし続けます。
> const char* c_str = str_stream.str().c_str();
こちらの場合は、str_stream にある実体から、一度、std::string が生成されて、この行を抜けると破棄される。
その破棄されたオブジェクトが提供していたポインタを見ているので、それは保証されないというところです。
std::string は、C文字列を内部的に持っていて、それをもとにデータを加工しているような実装が普通には考えられます。
strstream も、内部的に、string を持っていて、それをもとにデータを加工しているような実装が普通には考えられます。
その場合、「破棄された」といっても、C文字列が入っているメモリそのもには、(再利用されるまで)そのまま残っているケースがあります。
との場合には、たまたま、「破棄された」C文字列のポインタが、もともと、文字列が入っていた領域をポイントしていて、そこには、まだ、以前の文字列が残っているという可能性もあります。
この場合に、たまたま動いているように見えるということですね。
上記のような実装は、必須ではないですし、もしかしたら、破棄されるときにデータ領域をちゃんと消していく実装もあるかもしれません。
その場合は、動いていないように見えるということになるのでしょう。
No.4
- 回答日時:
MSDN で c_str() の戻り値を見ると
------- 引用 ------
The pointer value is not valid after calling a non-const function, including the destructor, in the basic_string class on the object.
-------------------
と書いてあるから、str_stream.str() で作成された一時オブジェクトが破棄された後、c_str の値は保証されないようですね。
単に string("aiueo").c_str() としてもやはり NG みたい。これはハマリそう。
No.3
- 回答日時:
あーなるほどーそうでしたか
私一般人なのでただ見てるだけのつもりだったんですけど
全角に気づいたので突っ込んでみただけなのでなんともですけど、
こちらでは全角取り除けば"aiueo33"って出ますよ?
素人なので不正確になってしまいますけど私のコンパイラは
gcc ver3.2 か 3.4.2
みたいですけど。
そちらは何をお使いで?
この回答への補足
ありがとうございます。
失礼しました。
こちらの環境はVC++2008 Express Editionです。
cygwinでgcc 3.4.4で同じコードをコンパイルして動かすと
問題なく動きました。
VCのバグか何かなのでしょうか…
それともgccではたまたま動いているだけなのでしょうか。
No.2
- 回答日時:
> const char* c_str = str_stream.str().c_str();
str_stream.str() で一時的に作られた string の寿命が
極めて短く、c_str() が評価された直後にデストラクト
されているのでしょうね。
この回答への補足
回答ありがとうございます。
なるほど、つまり、
const char* c_str = str_stream.str().c_str();
の行が終わった時点でstr()によって取得したstringオブジェクトは
破棄されてしまうというわけですか。
疑問があるのですが、これはC++の標準の動きなのでしょうか?
というのも、同じコードcygwinでg++でコンパイルしたら問題なく
動作しました。
書き忘れていたのですが、質問時のコードはVC++2008 Expressでコンパイルしました。
VC++9.0のバグ、ということはないでしょうか?
VC++9.0とg++ではどちらが正しい動きをしているのでしょうか?
No.1
- 回答日時:
"aiueo" << 33;
"と<<
のあいだに
全角スペースはいっとりまっせ~
これははまるは
そのまま貼り付けなかったら解決しませんでしたね
この回答への補足
すみません。全角スペースはタイプミスです。
手元のソースでは普通のスペースになっています。
コンパイルは通ることを確認しています。
失礼しました。
全角スペース問題ではないようです。
よくわからないのは、以下のようにするとうまく動くことです。
std::string moji = str_stream.str();
const char* c_str = moji.c_str();
どうして、
const char* c_str = str_stream.str().c_str();
と一行でまとめて書くとうまくいかないのでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# sprintf()の使い方について 1 2022/08/17 16:16
- PHP PostgreSQLからCSV形式でエクスポートする際にカラム内の改行をとる方法 1 2023/02/22 10:05
- C言語・C++・C# C# 浮動小数の数値文字列化 1 2022/04/18 15:15
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# C言語 少しの疑問 4 2022/11/08 02:48
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
char AA[]{"全角文字"};から"全...
-
fread()関数とfwrite()関数につ...
-
エクセルのMID関数は、C言語では?
-
C言語のintとcharの違いってな...
-
char型にint型の数値を代入する。
-
C言語 配列の長さの上限
-
先頭アドレスとは何ですか?
-
C# Listを使わずに2次元配列の...
-
配列の要素数に変数を入れたい...
-
関数から配列を返すには?
-
C言語のポインタに直接アドレス...
-
newしないオブジェクトについて
-
VBAの変数のデータ型を変更する...
-
あるディレクトリ内のファイル...
-
VBAのプログラムで、DIAG = 1# ...
-
[C#] DeviceIoControlの変数の型
-
c言語のポインタへの文字列入力...
-
変換
-
【速いブラインドタッチ】手を...
-
init関数の意味
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
char型にint型の数値を代入する。
-
C言語にて構造体のメンバがNULL...
-
fgetc( )の戻り値はなぜ整数??
-
char 文字列型 の表現範囲が-12...
-
fstream型オブジェクトを関数の...
-
C++17で、unsigned char * 配列...
-
DWORDとcharの変換
-
文字列内の数字削除
-
new charとnew char[N]の違いは?
-
文字型配列に格納した空白の切捨て
-
C++Builder 2009 テキスト...
-
csvファイルをfscanfで読み込む...
-
文字列の途中から途中までを抽出
-
[C] 構造体メンバーのカンマ区...
-
エクセルのMID関数は、C言語では?
-
小数点入りの文字列をfloat型に...
-
wsprintf( ポインタ , "%d" , "...
おすすめ情報