std::string::c_str() 和临时变量

2022-01-07 00:00:00 c++ stl stdstring

以下 C++ 代码格式是否正确:

Is the following C++ code well-formed:

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

std::string random_string_generator()
{
  // returns a random std::string object
}

consumer(random_string_generator().c_str());

我遇到的问题是,在创建临时 std::string 对象并获取 c_str() 指针后,没有什么可以阻止 std::string 对象被破坏(或者我可能错了?).如果代码没问题的话,你能不能给我指出标准.当我用 g++ 测试时,它确实有效.

The problem I have with it is, that after creating the temporary std::string object and taking the c_str() pointer, nothing prevents the std::string object from getting destroyed (or maybe I'm wrong?). Can you please point me to the standard, if the code is OK despite everything. It does work, when I test with g++.

推荐答案

std::string::c_str()返回的指针指向内存由字符串对象维护.它一直有效,直到非常量在字符串对象上调用函数,或者字符串对象是毁坏了.您关心的字符串对象是临时对象.它将在完整表达式的末尾销毁,而不是在之前和不是之后.在您的情况下,完整表达式的结尾在调用 consumer,所以你的代码是安全的.如果 consumer将指针保存在某处,以备后用.

The pointer returned by std::string::c_str() points to memory maintained by the string object. It remains valid until a non-const function is called on the string object, or the string object is destructed. The string object you're concerned about is a temporary. It will be destructed at the end of the full expression, not before and not after. In your case, the end of the full expression is after the call to consumer, so your code is safe. It wouldn't be if consumer saved the pointer somewhere, with the idea of using it later.

从 C++98 开始就严格定义了临时对象的生命周期.在此之前,它会有所不同,具体取决于编译器和您编写的代码编写的不会与 g++ 一起工作(1995 年之前,粗略地—g++当标准委员会投票时几乎立即改变了这一点).(那时也没有 std::string,但同样的问题会影响任何用户编写的字符串类.)

The lifetime of temporaries has been strictly defined since C++98. Before that, it varied, depending on the compiler, and the code you've written wouldn't have worked with g++ (pre 1995, roughly—g++ changed this almost immediately when the standards committee voted it). (There wasn't an std::string then either, but the same issues affect any user written string class.)

相关文章