9

我有一个函数将返回一个 char*。由于我必须连接一些字符串,所以我写了以下行:

std::string other_text;
// ...
func(("text" + other_text).c_str());

我知道我可以避免命名我要使用的字符串的问题。我只是想借此机会提出一个更普遍的问题:调用临时变量的方法是否安全?是否符合标准?

4

4 回答 4

14

调用临时变量的方法是安全的,但返回临时变量的 char* 以供以后使用是不安全的。

这个 char* 指向一个即将被释放的缓冲区。一旦它被释放,您将有一个指向内存中无效区域的指针。

相反,请返回一个 std::string 对象。

于 2009-03-31T14:45:49.273 回答
6

您可以在临时对象上调用方法,但是您必须注意对象的生命周期——特别是,如果您有一个c_str()在临时对象上调用返回的函数std::string,则该字符串对象将在函数返回时被销毁。

您上面的代码遇到了这个问题。

于 2009-03-31T14:48:05.337 回答
4

在临时对象上调用 c_str() 返回的 C 字符串将一直有效,直到下一次在临时对象上调用 c_str() 为止,这永远不会发生。临时变量本身挂在它所属的完整表达式的末尾(return 语句)。

如果您要返回一个 std::string,那么一切都将是 hunkydory,因为字符串的复制构造函数将在返回中被调用以获取副本。如果你返回一个 char *,那么所有的赌注都会被取消,因为你返回的值将在函数退出时被处理掉。这与临时没有任何特别的关系,这是返回 char * 时的普遍问题 - 更喜欢返回 std::strings 。

于 2009-03-31T14:51:55.470 回答
2

只要临时对象仍然存在,生成的指针就可以使用,通常直到表达式结束。例外情况是在初始化程序中使用临时变量(在这种情况下,它会持续到初始化结束),或者绑定到引用时。函数 return 语句中的临时语句会持续到函数退出(除非绑定到引用)。一旦临时生命周期结束,临时被销毁。在这种情况下,这意味着字符串析构函数运行,因此字符的内存被释放。换句话说,一旦返回值,它就保证无效。

您可以将字符串本身传回,将其作为 const 引用返回。您可以将 .c_str() 复制到新分配的内存,然后将其传回(作为指针或智能指针)。其中任何一个都行得通。

C++ 标准的第 12.2 节介绍了临时对象的生命周期。根据标准,您将返回一个指向已释放内存的指针。

于 2009-03-31T15:02:45.693 回答