web-dev-qa-db-ja.com

std :: string :: c_str()およびtemporaries

次のC++コードは整形式ですか?

void consumer(char const* p)
{
  std::printf("%s", p);
}

std::string random_string_generator()
{
  // returns a random std::string object
}

consumer(random_string_generator().c_str());

私が抱えている問題は、一時的なstd :: stringオブジェクトを作成し、c_str()ポインターを取得した後、std :: stringオブジェクトが破壊されるのを防ぐものがない(または私が間違っているのではないか)ことです。すべてにもかかわらずコードに問題がない場合は、標準を教えてください。 g ++でテストすると、機能します。

57
user1095108

std::string::c_str()によって返されるポインタは、文字列オブジェクトによって維持されるメモリを指します。非const関数が文字列オブジェクトで呼び出されるか、文字列オブジェクトが破棄されるまで有効です。気になる文字列オブジェクトは一時的なものです。それは完全な表現の終わりに破壊され、前でも後でも破壊されません。あなたの場合、完全な式の終わりはconsumerの呼び出しの後であるため、コードは安全です。 consumerがポインタをどこかに保存し、後で使用することを考えた場合はそうではありません。

一時の寿命はC++ 98以降厳密に定義されています。それ以前は、コンパイラーによって異なり、作成したコードはg ++では機能しませんでした(1995年以前は、大まかに言って、g ++は標準委員会が投票するとすぐにこれを変更しました)。 (当時はstd::stringもありませんでしたが、同じ問題がユーザーが記述した文字列クラスに影響します。)

67
James Kanze

一時的なstd::stringの存続期間はconsumerが返されるポイントを少し超えているため、その文字列には何でも使用しても安全ですconsumer内から直接not OKとは、次の値を格納することですc_str戻り、後でそれを使用しようとします(一時ファイルは破棄され、ポインタのもう一方の端で何が見つかるかしか推測できません)。

20
Jon

関数random_string_generator()が返す一時変数は、consumer()関数で安全に使用できます。

5
dgulabs