【问题标题】:Is writing to &str[0] buffer (of a std:string) well-defined behaviour in C++11?在 C++11 中写入 &str[0] 缓冲区(std:string)定义明确的行为吗?
【发布时间】:2014-08-06 20:48:18
【问题描述】:
char hello[] = "hello world";
std::string str;
str.resize(sizeof(hello)-1);
memcpy(&str[0], hello, sizeof(hello)-1);

此代码在 C++98 中是未定义的行为。在 C++11 中是否合法?

【问题讨论】:

  • std::string 缓冲区的新保证是连续的。但我不知道标准是否允许 writing 到该缓冲区,因为据我所知 std::string 的 COW 实现仍然是可能的。
  • 你到底为什么要这样做?
  • @user3791372 有很多好的理由。示例:string str; str.resize(8); fread(&str[0], 1, str.size(), file);
  • C++11 中不允许使用 COW。看到这个答案stackoverflow.com/questions/12199710/…
  • 所以在我看来,您的代码没有理由成为未定义的行为。

标签: c++ string c++11 buffer language-lawyer


【解决方案1】:

是的,代码在 C++11 中是合法的,因为 std::string 的存储保证是连续的,并且您的代码避免覆盖终止 NULL 字符(或初始化的值 CharT)。

来自 N3337,§21.4.5 [string.access]

 const_reference operator[](size_type pos) const;
 reference operator[](size_type pos);

1 需要: pos <= size()
2 返回: *(begin() + pos) 如果pos < size()。否则,返回对类型为 charT 且值为 charT() 的对象的引用,其中修改对象会导致未定义的行为。

您的示例满足上述要求,因此行为定义明确。

【讨论】:

  • #2 返回的引用需要多长时间有效?是否需要引用来引用连续存储?也就是说,符合要求的实现是否可以返回对char 的引用,该引用是所请求位置的副本,前提是它(以及它单独)的读取和写入符合预期?
  • @BCS 引用将在字符串的生命周期内有效,或者直到您执行使引用(和迭代器)无效的操作,通常是调整字符串的大小。除了上面引用的部分,还可以参考 [string.accessors]data() 成员函数的描述。在两者之间,很明显,符合要求的实现需要有连续的存储,operator[] 返回对此存储中元素的引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-14
  • 2023-03-08
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多