我同事的代码是这样的:
void copy(std::string const& s, char *d) {
for(int i = 0; i <= s.size(); i++, d++)
*d = s[i];
}
他的应用程序崩溃了,我认为这是因为访问 s
超出了范围,因为条件应该只达到 s.size() - 1
。
但我旁边的其他人说过去曾讨论过这是合法的。谁能帮我解决这个问题?
最佳答案
让我们撇开 *d
的可能性无效,因为这与问题似乎针对的内容无关:是否 std::string operator[]()
在访问索引 std::string::size()
处的“元素”时具有明确定义的行为.
C++03标准对string::operator[]()
的描述如下(21.3.4 "basic_string
元素访问"):
const_reference operator[](size_type pos) const; reference operator[](size_type pos);
Returns: If
pos < size()
, returnsdata()[pos]
. Otherwise, ifpos == size()
, the const version returnscharT()
. Otherwise, the behavior is undefined.
自 s
在示例代码中是 const
, 行为定义明确并且 s[s.size()]
将返回一个空字符。但是,如果 s
不是 const string
,行为将是未定义的。
C++11 补救了 const
的这种古怪行为在这种边缘情况下,版本的行为与非常量版本非常不同。 C++11 21.4.5“basic_string
元素访问”说:
const_reference operator[](size_type pos) const; reference operator[](size_type pos);
Requires:
pos <= size()
.Returns:
*(begin() + pos
) ifpos < size()
, otherwise a reference to an object of type T with valuecharT()
; the referenced value shall not be modified.
因此对于 C++11 编译器,行为是明确定义的,无论 string
是否存在。是const
.
与问题无关,我觉得 C++11 说“引用的值不得修改”有点奇怪——我不清楚该条款是否仅适用于 pos == size()
的情况。 .我很确定有大量现有代码可以执行类似 s[i] = some_character;
的操作。其中 s
是一个非常量 std:string
和 i < s.size()
.现在是未定义的行为吗?我怀疑该条款仅适用于特殊情况 charT()
对象。
另一个有趣的事情是,这两个标准似乎都没有要求为 s[s.size()]
返回对象的地址。以任何方式与为 s[s.size() - 1]
返回的对象的地址相关.换句话说,返回的似乎是 charT()
引用不必与字符串数据的末尾连续。我怀疑这是为了给实现者一个选择,如果需要,只返回对该哨兵元素的单个静态拷贝的引用(这也可以解释 C++11 的“不得修改”限制,假设它仅适用于特殊的例)。
关于c++ - C++ 中的 string[length()] 可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10570534/