使用临时字符串的 std::string::c_str() 安全吗?

问题描述 投票:0回答:3

以下 C++ 代码格式正确吗?

void consumer(char const* p)
{
  std::printf("%s", p);
}

std::string random_string_generator();

consumer(random_string_generator().c_str());

我遇到的问题是,在创建临时

std::string
对象并获取
c_str()
指针之后,没有什么可以阻止
std::string
对象被销毁,除非我错了。

这段代码的格式是否符合标准?当我用 g++ 测试时,它确实有效。

c++ stl language-lawyer stdstring temporary-objects
3个回答
90
投票

std::string::c_str()
返回的指针指向内存 由字符串对象维护。它一直有效,直到非常量 在字符串对象上调用函数,或者字符串对象是 被破坏了。您关心的字符串对象是临时的。 它将在完整表达式的末尾被破坏,而不是之前和 不是之后。在您的情况下,完整表达式的结尾位于 调用
consumer
,因此您的代码是安全的。就不会这样了
consumer
将指针保存在某处,以便稍后使用它。

自 C++98 起,临时变量的生命周期就被严格定义。 在此之前,它会有所不同,具体取决于编译器和您的代码 书面的不能与 g++ 一起工作(1995 年之前,大致 -g++ 当标准委员会投票时几乎立即改变了这一点)。 (当时也没有

std::string
,但同样的问题也会影响 任何用户编写的字符串类。)


25
投票

临时

std::string
的生命周期刚好超出
consumer
返回的点,因此直接从 consumer
 内使用该字符串 
上的任何内容都是安全的。 可以的是存储
c_str
返回的值并稍后尝试使用它(临时将被破坏,我们只能猜测你会在指针的另一端找到什么)。


6
投票

random_string_generator()函数返回的临时值可以安全地在consumer()函数中使用。

© www.soinside.com 2019 - 2024. All rights reserved.