带字符串的out_of_range异常

时间:2015-07-20 17:11:10

标签: c++ exception indexoutofboundsexception

我试图理解字符串中的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

3 个答案:

答案 0 :(得分:1)

这是因为[]运算符不会检查任何内容,而在()处。 CppReference说:

的std :: basic_string的::在

  

返回对指定位置pos处的字符的引用。执行边界检查,将在无效访问时抛出std :: out_of_range类型的异常。

的std :: basic_string的::运算符[]

  

返回对指定位置pos处的字符的引用。不执行边界检查。

答案 1 :(得分:1)

std::string::atstd::string::operator[]的工作方式不同。

  • at(size_t)方法检查字符串的当前大小:如果超出范围,则会抛出异常。

  • operator[](size_t)是对大块内存的直接访问。所以问题出在运行期间。

std::string::operator[]

std::string::at

答案 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()。” 功能