【问题标题】:Why shouldn't I use std::string.c_str() as a buffer?为什么我不应该使用 std::string.c_str() 作为缓冲区?
【发布时间】:2013-02-21 22:40:58
【问题描述】:

虽然这很可能是一个愚蠢的问题,但我看到了一些关于你不应该这样做的内容,尽管 C++ 11 允许这样做,但我不太明白为什么。谁能解释这是为什么?

【问题讨论】:

  • 你指的是this吗?
  • 嗯,它是const——不可变缓冲区对你有用吗?
  • C++11不允许
  • @juanchopanza : 在 C++11 中使用std::string 作为缓冲区是允许的,只是通过&str[0] 而不是str.c_str()
  • @RT_34,未定义的行为似乎在许多情况下都可以正常工作。几个月后,它就不会了。

标签: c++ stdstring


【解决方案1】:

这是不允许的!

21.4.7 basic_string 字符串操作[string.ops]

21.4.7.1 basic_string 访问器[string.accessors]

const charT* c_str() const noexcept;
const charT* data() const noexcept;
  1. 返回:一个指针 p,使得 p + i == &operator 用于 [0,size()] 中的每个 i。
  2. 复杂性:恒定时间。
  3. 要求:程序不得更改存储在字符数组中的任何值。

除此之外,您正在通过const char * 修改数据引用,这通常表示const_cast<char*>。这不仅会导致未定义的行为,而且根据 Herb Sutter 的说法,const 现在应该被视为线程安全的 (see his talk about const and mutable)。

然而,正如前面所说,如果str 足够大,使用std::string str; &str[0] 是安全的。只是不要使用.c_str().data()

【讨论】:

  • const_cast 仅在以下情况下才会导致未定义的行为.第二部分是正确的,第一部分取决于调用c_str() 的字符串是否为常量(即使它是常量,也可能是缓冲区仍然不是常量......)。话虽如此,更好的方法是使用&str[0]
猜你喜欢
  • 2014-12-20
  • 1970-01-01
  • 2010-11-03
  • 2016-07-10
  • 2014-04-02
  • 1970-01-01
  • 2019-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多