考虑以下非常简单的文本示例:
#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;
}
我希望程序迭代字符串的所有字符,然后到达空终止字符,打破循环并正确到达程序结束。 但是,当我尝试在Visual Studio 2010下以调试模式编译它时,我到达了一个异常“字符串下标超出范围”。 在发布模式下编译时,这个程序会通过,但是我的大项目取决于这种行为崩溃 - 也许是因为这个问题。
但是,当我在www.cplusplus.com检查std::string::operator[]
的规范时,会明确处理结束字符串:
如果pos等于字符串长度,则该函数返回对空字符('\ 0')的引用。
我想在这里问:
std::string
规范的解释是否正确?或者我错过了什么?length()
时都不会调用operator[]
?例如使用c_str()[i]
会安全吗?答案 0 :(得分:7)
这是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&lt; = size()。
2返回:
*(begin() + pos)
ifpos < size()
,否则对T
类型的对象的引用,其值为charT();
,不得修改引用的值。