【问题标题】:out_of_range exception with strings字符串的 out_of_range 异常
【发布时间】:2015-10-09 22:07:03
【问题描述】:

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

【问题讨论】:

    标签: c++ exception indexoutofboundsexception


    【解决方案1】:

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

    std::basic_string::at

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

    std::basic_string::operator[]

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

    【讨论】:

      【解决方案2】:

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

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

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

      std::string::operator[]

      std::string::at

      【讨论】:

        【解决方案3】:

        使用长度为 n 的字符串 s,您可以使用 []at 访问索引 0 到 n-1 处的项目,具有明确定义的行为。

        通过[]访问索引n处的项目(1)保证产生对零对象的引用,而通过at访问它是(2)保证抛出out_of_range异常。

        前一种行为是为了与 C 编程的期望兼容,而后一种行为是为了确保正确性。

        确实,at 方法保证为 0 到 n-1 范围之外的任何索引抛出 out_of_range 异常。

        使用[],您访问的索引(3)要求在 0 到 n 的范围内。这意味着使用超出该范围的索引是未定义的行为。


        1) C++14 21.4.5/2 关于basic_string::operator[]:“返回*(begin() + pos) 如果pos &lt; size()。否则,返回对类型对象的引用 charT 的值为 charT(),其中修改对象会导致未定义的行为”。
        2)。 C++14 21.4.6/5 about basic_string::at: “Throws: out_of_range if pos &gt;= size()”,其中索引类型是无符号的。
        3) sup> C++14 21.4.5/1 关于basic_string::operator[]:“需要pos &lt;= size。”

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-25
          • 2017-11-26
          • 1970-01-01
          • 2012-07-25
          • 1970-01-01
          相关资源
          最近更新 更多