2012-04-04 40 views
45

是对以下C++代码合式:的std :: string :: c_str()和临时

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 ++测试时。

回答

56

std::string::c_str()返回的指针指向由字符串对象维护的内存 。直到在字符串对象上调用非const 函数或字符串对象为 遭到破坏,它才有效。你关心的字符串对象是一个临时对象。 它将在完整表达式的末尾被破坏,而不是在之前和之后。在你的情况下,完整表达式的结尾在 调用consumer之后,所以你的代码是安全的。如果consumer 将指针保存在某处,并且稍后使用它,则不是。

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

18

临时std::string的寿命延长刚刚超越的地步consumer回报,因此它是安全的从consumer内该字符串直接使用任何东西。什么是而不是好的是存储c_str返回的值,并在稍后尝试使用它(临时将被销毁,我们只能猜测在指针的另一端会发现什么)。

+1

您能否提供关于C++ 03或C++ 11标准的提示? – user1095108 2012-04-04 07:53:01

+3

临时的生命周期在§12.2中定义。 (第12部分是 ,标题为“特殊成员函数”,它不是 期望寻找临时对象的生命期的地方,但这就是它的位置。) – 2012-04-04 07:56:24

+0

@ user1095108函数参数的生命周期可以从§ 3.2.2和§3.7.2在C++ 03标准中。 – juanchopanza 2012-04-04 08:24:46

5

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

相关问题