2

考虑以下非常简单的文本示例:

#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.comstd::string::operator[]的规范时,会显式处理结束字符串:

如果 pos 等于字符串长度,则函数返回对空字符 ('\0') 的引用。

我想在这里问:

  • 我对规范的解释是否std::string正确?还是我错过了什么?
  • 如果问题出在实现的 VS 方面,我怎样才能轻松解决这个问题 - 希望length()每次我使用operator[]? 例如,使用c_str()[i]会安全吗?
  • 如果问题出在 VS 的实施方面 - 你知道它是否在 VS 2012 中得到修复,或者将来可能会得到修复?
4

1 回答 1

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 <= size()。

2 返回:*(begin() + pos)if pos < size(),否则对T具有值charT();的类型对象的引用不应修改所引用的值。

于 2013-08-18T13:41:57.470 回答