这是明确定义的行为吗?
const char* p = (std::string("Hello") + std::string("World")).c_str();
std::cout << p;
我不确定。原因是什么?
答案 0 :(得分:6)
不,这是未定义的行为。 std::string
临时值和operator+
返回的临时值仅存在于const char*
(完整表达式结束)初始化结束之前。然后他们被摧毁,p
指向不确定的记忆。
答案 1 :(得分:2)
由于p
指向std::cout << p;
创建临时以保留std::string("Hello") + std::string("World")
。然后从该对象中恢复C风格的字符串。在表达式结束时,临时销毁,p
指向已释放的存储。
使用p
然后调用未定义的行为。
有两种情况下,临时表在与完整表达结束时不同的点被销毁。第一个上下文是表达式作为定义对象的声明符的初始值设定项。在该上下文中,保存表达式结果的临时值应持续到对象的为止 初始化完成。
....
答案 2 :(得分:1)
由于缺少分号而无法编译:
const char* p = (std::string("Hello") + std::string("World")).c_str(); //<< important here
std::cout << p;
现在该规则适用于在使用它的表达式的末尾删除临时值,即分号。因此,您有一个指向已删除内存的指针,这会导致未定义的行为。
答案 3 :(得分:0)
我最近阅读了这本优秀的书籍http://www.amazon.co.uk/Gotchas-Avoiding-Addison-Wesley-Professional-Computing/dp/0321125185/ref,如果我没记错的话,这几乎是其中一个例子。
我相信从c_str
返回的数据只有返回它的字符串对象是有效的才有效。示例中的字符串对象仅在表达式的持续时间内有效。