C++ 使用(str1+str2).c_str()安全吗?

C++ 使用(str1+str2).c_str()安全吗?,c++,string,C++,String,我已经测试了这段代码: #include <iostream> #include <cstdio> #include <string> using namespace std; int main() { string s1("a"),s2("b"); const char * s = (s1+s2).c_str(); printf("%s\n",s); } 它返回ab 据我所知,由于s1+s2是一个临时对象,可能会以某种方式消失,我

我已经测试了这段代码:

#include <iostream>
#include <cstdio>
#include <string>
using namespace std;

int main()
{
    string s1("a"),s2("b");
    const char * s = (s1+s2).c_str();
    printf("%s\n",s);
}
它返回ab

据我所知,由于s1+s2是一个临时对象,可能会以某种方式消失,我对此一无所知,那么const char*s可能指向未定义的内存,并可能被转储


那么这样使用.c_str安全吗?

在您的示例中不安全。不管怎样,它是安全的

printf("%s\n", (a + b).c_str());
原因是临时值(如a+b的结果)在完整表达式的末尾被销毁。在您的示例中,const char*保留了包含临时变量的完整表达式,并且取消引用它是未定义的行为


未定义行为中最糟糕的部分是,不管怎样,事情显然是可行的。。。只有在包括父母在内的广大观众面前进行演示时,UB代码才会崩溃;-

在该示例中,我们可以引用以下标准:

12.2临时对象[类别临时]

临时对象作为计算完整表达式1.9的最后一步被销毁,完整表达式1.9在词汇上包含创建临时对象的点。即使评估以抛出异常结束,这也是正确的。销毁临时对象的值计算和副作用仅与完整表达式关联,而不与任何特定的子表达式关联

这是在您行的分号之后:

const char * s = (s1+s2).c_str(); // <- Here
为什么??因为当你的物体被破坏时,你不再知道这个地方现在是什么

这里的糟糕之处在于,对于未定义的行为,您的程序在第一次运行时似乎可以正常工作,但是。。。它肯定会在最坏的时候崩溃

你可以做:

printf( "%s\n", (s1+s2).c_str() );

它可以工作,因为对象还没有被破坏请记住,在分号之后…

它不安全,但是您可以轻松地分配给一个新变量,指针在该变量的范围内是安全的:

string s1("a"), s2("b") , s3;
s3 = s1 + s2;
printf("%s\n", s3.c_str());

//other operations with s3

像大多数编程结构一样,如果正确使用它,它是安全的,如果你马虎,它是不安全的。在这种情况下,正确使用它意味着关注对象的生命周期。+运算符创建一个临时对象,该对象在语句末尾被销毁,返回的const char*在创建它的语句之后不再有效。因此,您可以将c_str的结果直接传递给函数,但不能保存指针并在以后使用。

插入字符串s3Oh no!;就在printf之前,您的输出很可能会改变。但这并不能保证。在同一个完整的表达中,可能的重复是根本不同的用法。我在那里发现了一些痛苦的记忆吗;您能指出在完整表达式的末尾,临时值(如a+b的结果)被销毁的位置吗。是在规范中指定的吗?@Nirk标准文本请参见Pierre Fourgeaud的答案。@catchmeifyoutry:不是真的。。。更像:-这里没有删除;这个词被破坏了。在C++中,它们有不同的含义。我刚刚改正了!谢谢你指出这一点!
string s1("a"), s2("b") , s3;
s3 = s1 + s2;
printf("%s\n", s3.c_str());

//other operations with s3