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