C++ 临时字符串的生命周期

4

抱歉,我知道有类似的问题存在,但我仍然不是完全清楚。以下内容是否安全?

void copyStr(const char* s)
{
    strcpy(otherVar, s);
}

std::string getStr()
{
    return "foo";
}

main()
{
    copyStr(getStr().c_str());
}

一个临时的std::string将存储从getStr()返回的值,但它是否能够存活足够长的时间,以便我可以将其C字符串复制到其他地方?还是必须显式为其保留一个变量,例如

std::string temp = getStr();
copyStr(temp.c_str());
3个回答

5

是的,这是安全的。从getStr获得的临时变量将一直存在到它所在的完整表达式结束。该完整表达式是copyStr调用,因此必须在从getStr获取的临时变量被销毁之前返回。这已经足够了。


根据我的理解,对于这种情况,从字符串字面量“foo”创建了一个字符串对象并返回它(可能通过复制省略),当我们说getStr().c_str()时,它可能不是指向确切的字符串字面量。这正确吗? - bsguru
@bsguru:正确。理论上,C++标准允许“as-if”优化,但在实践中,对于这种情况仍然是不可行的。 - MSalters

3

临时变量的生命周期持续到整个表达式结束。因此,在您的示例中,

copyStr(getStr().c_str());

getStr()的返回值将一直存在,直到copyStr结束。因此,在copyStr中访问其值是安全的。当然,您的代码仍然可能不安全,因为它没有测试缓冲区是否足够大以容纳字符串。


0

你需要声明一个临时变量并将返回结果赋值给它:

...
{
  std::string tmp = getStr();
  //tmp live
  ...
}
//tmp dead
...

临时变量必须有一个名称,并将存在于其声明的范围内。

编辑:它是安全的,您可以通过复制的值传递它(您的编辑很重,使我上面的答案无效。上面的答案涉及第一个修订版)

copyStr(getStr().c_str());将rvalue传递给copyStr()


是的,我混淆了左值和右值,抱歉已经修改了。 - user1585121
这不是我的意思,其余的也是错的:“一个临时变量必须要有名字” - 不,恰恰相反:一个临时变量不能够有名字。 - Konrad Rudolph
@KonradRudolph 我说“编辑:问题使我的上面的回答无效了” 看看第一个修订版本,在他编辑之前。他写了std::string getStr(); - user1585121
好的,答案已经开始了:“你必须声明一个临时变量”——它们也没有被声明。但是Konrad和我使用ISO标准中定义的正式术语“temporary”,显然这个答案使用了一个(令人困惑的)不同含义。 - MSalters
我理解它与您相同的正式术语,但显然OP指的是他命名为temp的变量。为了澄清起见,我只是使用了临时这个词,与问题中的混淆含义相同。请检查问题的修订版本并重新阅读我的答案,也许可以重新考虑您的负评。 - user1585121

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