考虑以下非常简单的文本示例:
#include <stdio.h>
#include <string>
int main() {
std::string x("ugabuga");
int i=0;
while (x[i]) {
++i;
}
printf("%d\n",i); //should print 7
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望程序迭代字符串的所有字符,然后到达空终止字符,打破循环并正确到达程序结束.但是,当我尝试在Visual Studio 2010下以调试模式编译它时,我到达了一个异常"字符串下标超出范围".在发布模式下编译时,这个程序会通过,但是我的大项目取决于这种行为崩溃 - 也许是因为这个问题.
但是,当我检查www.cplusplus.com的规范std::string::operator[]时,显式处理结束字符串:
如果pos等于字符串长度,则该函数返回对空字符('\ 0')的引用.
我想问一下:
std::string是否正确?或者我错过了什么?length()每次使用时都不用调用operator[]?例如,使用c_str()[i]会安全吗?这是C++ 03和C++ 11之间发生变化的事情之一.
它似乎是C++ 03中未定义的行为:
21.3.4 basic_string元素访问[lib.string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);1返回:如果
pos < size(),则返回data()[pos].否则,如果pos == size(),const version returns charT().否则,行为未定义.
而在C++ 11中,没关系.
21.4.5 basic_string元素访问[string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);1要求:pos <= size().
2返回:
*(begin() + pos)ifpos < size(),否则不应修改对T具有值charT();的类型的对象的引用.