访问std :: string中的空终止字符(字符串下标超出范围)

Cyg*_*sX1 2 c++ visual-c++

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

#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是否正确?或者我错过了什么?
  • 如果问题出在VS的实现方面,我怎么能轻松解决这个问题 - 希望length()每次使用时都不用调用operator[]?例如,使用c_str()[i]会安全吗?
  • 如果问题出在VS的实施方面 - 你知道它是否在VS 2012中修复了,或者将来是否会修复pehaps?

jua*_*nza 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();的类型的对象的引用.