【问题标题】:std::string::c_str() and temporariesstd::string::c_str() 和临时文件
【发布时间】:2012-04-17 21:52:32
【问题描述】:

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

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++ 进行测试时,它确实有效。

【问题讨论】:

    标签: c++ stl stdstring


    【解决方案1】:

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

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

    【讨论】:

    • 如果在后续语句中使用c_str() const char* 会怎样(仍在函数内部,但在第一个语句之外)?这会给我们带来一个悬空指针吗?
    • 我自己回答...在这种情况下它是无效的:§ 12.2 ... 作为评估完整表达式 (1.9) 的最后一步,临时对象被销毁(词法上) ) 包含它们的创建点。即使评估以抛出异常结束也是如此。
    • std::string temp = random_string_generator().c_str();假设温度是正确的,这是正确的吗?因为从 random_string_generator() 返回的字符串的生命周期将一直到表达式结束?
    【解决方案2】:

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

    【讨论】:

    • 能否提供关于 C++03 或 C++11 标准的提示?
    • 临时文件的生命周期在 §12.2 中定义。 (第 12 节的标题是“特殊成员函数”,这并不是您期望寻找临时对象生命周期的地方,但这就是它所在的地方。)
    • @user1095108 和函数参数的生命周期可以从 c++03 标准的 §3.2.2 和 §3.7.2 获得。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 2023-01-11
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      相关资源
      最近更新 更多