如果我写如下,我想知道void func(const char *str);
引用是否有效:str
auto str = string("hello").c_str();
func(str);
它与下面的代码有何不同?
func(string("hello").c_str())
在这两种情况下,string
对象都是临时的,在语句结束时被销毁。
在第一种情况下,str
最终悬空指向由临时管理string
但现在已被销毁的内存。用它做任何事情都是错误的,会给出未定义的行为。
在第二种情况下,string
直到函数返回后才会销毁临时对象。所以这很好,只要函数不保留指针以供以后使用。
不同之处在于第一个创建了一个临时string
对象,该对象在第一条语句的末尾被销毁,因此str
成为一个悬空指针。第二个也创建了一个临时对象,但它存在于整个调用过程中,func
因为在调用返回之前临时对象不会被销毁func
。
来自 C++11 标准的第 12.2/3 段:
[...] 临时对象作为评估完整表达式 (1.9) 的最后一步被销毁,该完整表达式 (从词法上) 包含创建它们的点。即使评估以抛出异常结束也是如此。[...]
这意味着在包含调用的表达式中创建的临时func()
变量将一直存在,直到函数调用返回。
另一方面,第一个代码片段中临时的生命周期将在func()
被调用之前结束,并且str
将是悬空的。这将导致未定义的行为。