66

次の 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 ++でテストするとうまくいきます。

4

3 に答える 3

80

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

C++98 以降、一時オブジェクトの有効期間は厳密に定義されています。それ以前は、コンパイラによって異なり、作成したコードは g++ では機能しませんでした (1995 年より前、大まかに言えば、g++ は標準化委員会が投票した直後にこれを変更しました)。( std::stringthen どちらもありませんでしたが、同じ問題がユーザーが作成した文字列クラスに影響します。)

于 2012-04-04T07:53:57.123 に答える
23

temporarystd::stringの存続期間は、 return が返される時点を超えて延長されるため、その文字列に対して内から直接consumer何かを使用しても安全です。よくないのは、返された値を保存して後で使用しようとすることです (一時的な値は破棄されており、ポインターの反対側にあるものを推測することしかできません)。consumerc_str

于 2012-04-04T07:48:16.373 に答える
5

関数 random_string_generator() によって返される一時は、consumer() 関数で安全に使用できます。

于 2012-04-04T07:48:57.087 に答える