【问题标题】:Lifetime of returned strings and their .c_str() [duplicate]返回字符串的生命周期及其 .c_str() [重复]
【发布时间】:2017-05-05 13:36:57
【问题描述】:

我遇到过这种模式的多个实例(仅以 boost::filesystem 为例):

boost::filesystem::path path = ...;
someFunctionTakingCStrings(path.string().c_str());

在哪里

const std::string path::string() const
{
  std::string tmp = ...
  return tmp;
}

虽然我从未遇到过这种模式的问题,但我想知道sting() 返回的字符串何时被销毁,以及访问c_str() 的代码是否像c_str() lifetime is bound to std::string lifetime 一样安全。

【问题讨论】:

  • 为什么它被标记为 C 问题?
  • 因为里面有 c_str()
  • @PhilLab: 但这并不意味着它会在 C 中编译 ;-)

标签: c++ string std stdstring


【解决方案1】:

someFunctionTakingCStrings(path.string().c_str()); 是安全的,因为该标准保证匿名临时 path.string() 的生命周期在函数调用中仍然存在。所以c_str()返回的指针是someFunctionTakingCStrings的有效参数。

const std::string path::string() const 是安全的,因为从概念上讲,您正在返回 tmp 的值副本,尽管实际上编译器会优化该值副本(一个称为命名返回值优化的过程) .

const std::string& path::string() const 这样的函数体与你所拥有的函数体相同不会被定义(因为引用会悬空),并且

const char* ub_server()
{
    std::string s = "Hello";
    return s.c_str();
}

也是未定义的,因为s 在函数返回时已超出范围。

最后,请注意,在标准 C++ 中不允许在函数调用中将指向匿名临时的指针作为参数,尽管令人讨厌的是,Visual C++ 允许它作为扩展。

【讨论】:

  • 谢谢。快速跟进:那么,functionTakingPointer(&path.string()) 也会安全吗?
  • @PhilLab:不,它在标准 C++ 中是不安全的。我已将其放在答案的末尾。
  • hm,那我还没有完全理解 path.string() 的生命周期。或者匿名临时人员是关于内存管理的一整章?
  • @PhilLab:差不多就是这样,是的。圣诞节期间给你一些不错的读物。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 2015-01-22
  • 1970-01-01
相关资源
最近更新 更多