2

这是明确定义的行为吗?

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

我不知道。原因?

4

4 回答 4

6

不,这是未定义的行为。临时std::string对象和由返回的临时对象operator+都只存在到您的初始化const char*结束(完整表达式结束)。然后它们被破坏并p指向不确定的记忆。

于 2011-04-22T15:16:56.993 回答
2

不,行为未定义,因为p指向已释放的存储空间std::cout << p;

创建一个临时的来保存std::string("Hello") + std::string("World")。然后从该对象中检索 C 样式字符串。在表达式的末尾,临时被销毁,p指向一个已释放的存储。

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

12.2/4 说

在两种情况下,临时对象在与完整表达式结束时不同的点被销毁。第一个上下文是当表达式作为定义对象的声明符的初始值设定项出现时。在这种情况下,保存表达式结果的临时变量将持续存在,直到对象的初始化完成。
……

于 2011-04-22T15:15:50.500 回答
1

由于缺少分号,它不会编译:

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

现在,该规则适用于在使用它的表达式的末尾删除临时变量,该表达式位于分号处。因此,您有一个指向已删除内存的指针,这会导致未定义的行为。

于 2011-04-22T15:17:42.250 回答
0

我最近读了这本很棒的书http://www.amazon.co.uk/Gotchas-Avoiding-Addison-Wesley-Professional-Computing/dp/0321125185/ref如果我没记错的话,这几乎是那里给出的例子之一.

我相信从返回的数据c_str只有在返回它的字符串对象是活动的时候才有效。您示例中的字符串对象仅在表达式期间有效。

于 2011-04-22T15:19:05.290 回答