访问 std::string 中的空终止字符(字符串下标超出范围) [英] Accessing null-termination character in std::string (string subscript out of range)
问题描述
考虑以下非常简单的文本示例:
Consider the following very simple text example:
#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 下以调试模式编译它时,我遇到了异常字符串下标超出范围".在发布模式下编译时,该程序通过了,但我基于此行为的更大项目崩溃了 - 可能是因为这个问题.
I would expect the program to iterate over all characters of the string, then reach the null-terminating character breaking the loop and reach the program end correctly. However, when I tried compiling it in debug mode under Visual Studio 2010 I am reaching an exception "string subscript out of range". When compiling in release mode this program passes, but my bigger project depending on this behaviour crashes - perhaps because of this issue.
但是,当我在 www.cplusplus.com,明确处理结束字符串:
However, when I checked the specification of std::string::operator[]
at www.cplusplus.com, the end-character string is handled explicitly:
如果 pos 等于字符串长度,则函数返回对空字符('\0')的引用.
If pos is equal to the string length, the function returns a reference to a null character ('\0').
我想问一下:
- 我对
std::string
规范的解释是否正确?还是我遗漏了什么? - 如果问题出在 VS 的实现方面,我该如何轻松解决这个问题——希望每次使用
operator[]
时都不会调用length()
?例如使用c_str()[i]
会安全吗? - 如果问题出在 VS 的实现方面 - 您知道它是否在 VS 2012 中得到修复,或者未来是否会得到修复?
- Is my interpretation of specification of
std::string
correct? Or am I missing something? - If the problem lies on VS side of implementation, how can I easily fix this - hopefully without calling
length()
each time I use theoperator[]
? e.g. will usingc_str()[i]
will be safe? - If the problem lies on VS side of implementation - do you know if it is fixed in VS 2012 or pehaps will be fixed in the future?
推荐答案
这是 C++03 和 C++11 之间发生变化的事情之一.
This is one of the things that changed between C++03 and C++11.
这似乎是 C++03 中未定义的行为:
It seems it is undefined behaviour in C++03:
21.3.4 basic_string 元素访问[lib.string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
1 返回:如果 pos
data()[pos]
.否则,如果 pos == size()
,const 版本返回 charT()
.否则,行为未定义.
1 Returns: If pos < size()
, returns data()[pos]
. Otherwise, if pos == size()
, the const version returns charT()
. Otherwise, the behavior is undefined.
虽然在 C++11 中是可以的.
while in C++11, it is OK.
21.4.5 basic_string 元素访问[string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
1 要求:pos <= size().
1 Requires: pos <= size().
2 返回:*(begin() + pos)
如果 pos
T
且值为 charT();
的对象,引用的值不得修改.
2 Returns: *(begin() + pos)
if pos < size()
, otherwise a reference to an object of type T
with value charT();
the referenced value shall not be modified.
这篇关于访问 std::string 中的空终止字符(字符串下标超出范围)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!