我试图理解字符串中的out_of_range
异常
#include<iostream>
#include<exception>
using namespace std;
int main()
{
try{
string str = "Hello";
str.at(100);//throws exception and get caught
//str[100]; //this is a run time error, program crashes
}
catch (out_of_range &e)
{
cout << e.what() << endl;
}
}
为什么没有字符串数组访问会抛出任何异常和崩溃,而.at
工作正常?
IDE:VS2013
答案 0 :(得分:1)
这是因为[]运算符不会检查任何内容,而在()处。 CppReference说:
的std :: basic_string的::在
返回对指定位置pos处的字符的引用。执行边界检查,将在无效访问时抛出std :: out_of_range类型的异常。
的std :: basic_string的::运算符[]
返回对指定位置pos处的字符的引用。不执行边界检查。
答案 1 :(得分:1)
std::string::at
和std::string::operator[]
的工作方式不同。
at(size_t)
方法检查字符串的当前大小:如果超出范围,则会抛出异常。
operator[](size_t)
是对大块内存的直接访问。所以问题出在运行期间。
答案 2 :(得分:1)
使用长度 n 的字符串s
,您可以访问索引0到 n -1的项目,包括[]
和at
,具有明确定义的行为。
通过[]
访问索引 n 的项目是(1)保证产生对零对象的引用,同时通过{{1}访问它是(2)保证抛出at
异常。
前者的行为是为了兼容C编程的期望,而后者的行为是为了确保正确性。
实际上,out_of_range
方法可以保证为0到 n -1范围之外的任何索引抛出at
异常。
使用out_of_range
,您访问的索引是(3) required ,范围为0到 n 。这意味着使用该范围之外的索引是未定义行为。
1) C ++ 14 21.4.5 / 2关于[]
:“返回:basic_string::operator[]
如果*(begin() + pos)
。否则,返回对类型对象的引用
值pos < size()
的{{1}},其中修改对象会导致未定义的行为“
2)。 C ++ 14 21.4.6 / 5关于charT
:“引发:charT()
如果basic_string::at
”,其中索引类型是无符号的。
3) C ++ 14 21.4.5 / 1关于out_of_range
:“需要:pos >= size()
。”
功能