关于string.c_str()的生命周期

3
我想知道如果我按照以下方式编写代码:void func(const char *str);,是否会引用有效的str
auto str = string("hello").c_str();
func(str);

与下面的代码有何不同?
func(string("hello").c_str())

你是指 func(str); 吗? - us2012
你是不是指的是 func("hello");? :-) - Bo Persson
3个回答

8
在这两种情况下,`string`对象都是临时创建的,在语句结束后就会被销毁。
在第一种情况下,`str`成为了悬空指针,指向一个由临时的`string`管理的内存,但该内存现在已经被销毁。对它进行任何操作都是错误的,并产生未定义的行为。
在第二种情况下,临时的`string`直到函数返回之后才被销毁。只要函数不保留指针以供稍后其他用途使用,这样做就没问题。

+1 表示函数可能会保留指针以供稍后使用。 - Carl

6
区别在于第一个创建了一个临时的 string 对象,在第一条语句结束时被销毁,所以 str 变成了一个悬空指针。第二个也创建了一个临时对象,但它会在调用 func 结束之前一直存在,因为这个临时对象在调用 func 后才被销毁。

很好的发现。是的,临时变量将在第一条语句结束时被销毁,因为对c_str()的调用有效地意味着str是一个const char*,而不是一个字符串对象的引用(假设string与std::string相同)。 - Carl

3

根据C++11标准的第12.2/3段:

临时对象被销毁是在它们被创建的表达式所在的全序列中(词法上),作为最后一步。即使这个计算以抛出异常结束,也是如此。

这意味着包含对func()调用的表达式内部创建的临时对象将一直存在,直到函数调用返回。

另一方面,第一个代码片段中的临时对象的生命周期会在调用func()之前结束,导致str成为悬空指针。这将导致未定义行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接