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()由字符串对象维护的内存。在对字符串对象调用非常量函数或字符串对象被破坏之前,它一直有效。您关心的字符串对象是临时的。它将在完整表达式的末尾被破坏,而不是之前和之后。在您的情况下,完整表达式的结尾在对 的调用之后consumer,因此您的代码是安全的。如果consumer 将指针保存在某处,则不会是以后使用它的想法。

自 C++98 以来,临时对象的生命周期已被严格定义。在此之前,它会因编译器的不同而有所不同,而且您编写的代码无法与 g++ 一起使用(1995 年之前,大概——g++ 在标准委员会投票时几乎立即改变了这一点)。(当时也没有std::string,但同样的问题会影响任何用户编写的字符串类。)

于 2012-04-04T07:53:57.123 回答
23

临时std::string的生命周期刚好超出consumer返回点,因此直接从内部consumer使用该字符串上的任何内容是安全的。不好的是将返回的值存储c_str起来,以后再尝试使用(临时的会被销毁,我们只能猜测你会在指针的另一端找到什么)。

于 2012-04-04T07:48:16.373 回答
5

函数 random_string_generator() 返回的临时值可以安全地用于 consumer() 函数。

于 2012-04-04T07:48:57.087 回答