临时和表达行为

时间:2011-04-22 15:13:55

标签: c++ undefined-behavior temporary

这是明确定义的行为吗?

const char* p = (std::string("Hello") + std::string("World")).c_str();
std::cout << p;

我不确定。原因是什么?

4 个答案:

答案 0 :(得分:6)

不,这是未定义的行为。 std::string临时值和operator+返回的临时值仅存在于const char*(完整表达式结束)初始化结束之前。然后他们被摧毁,p指向不确定的记忆。

答案 1 :(得分:2)

由于p指向std::cout << p;

中的已解除分配存储,因此未定义此行为

创建临时以保留std::string("Hello") + std::string("World")。然后从该对象中恢复C风格的字符串。在表达式结束时,临时销毁,p指向已释放的存储。

使用p然后调用未定义的行为。

12.2 / 4说

  

有两种情况下,临时表在与完整表达结束时不同的点被销毁。第一个上下文是表达式作为定义对象的声明符的初始值设定项。在该上下文中,保存表达式结果的临时值应持续到对象的为止   初始化完成。
  ....

答案 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返回的数据只有返回它的字符串对象是有效的才有效。示例中的字符串对象仅在表达式的持续时间内有效。