Я пытался понять 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
Это потому, что оператор [] ничего не проверяет, а at () делает. CppReference говорит:
станд :: basic_string :: на
Возвращает ссылку на символ в указанном месте поз. Проверка границ выполняется, исключение типа std :: out_of_range будет выдано при недопустимом доступе.
станд :: basic_string :: Оператор []
Возвращает ссылку на символ в указанном месте поз. Проверка границ не выполняется.
std::string::at
а также std::string::operator[]
работать по-другому.
at(size_t)
Метод проверяет текущий размер строки: если она выходит за границы — она выдаст исключение.
operator[](size_t)
это прямой доступ к куску памяти. Так что проблема будет во время выполнения.
Со строкой s
длины N Вы можете получить доступ к пунктам с индексами от 0 до N-1 включительно, с обоими []
а также at
с четко определенным поведением.
Доступ к элементу по индексу N с помощью []
является (1)гарантированно даст ссылку на нулевой объект при доступе к нему через at
является (2)гарантированно бросить out_of_range
исключение.
Первое поведение предназначено для совместимости с ожиданиями программирования на С, а второе — для гарантированной корректности.
Действительно, at
метод гарантированно бросить out_of_range
исключение для любого индекса вне диапазона от 0 до N-1.
С []
индекс, к которому вы получаете доступ (3)требуется находиться в диапазоне от 0 до N. А это означает, что использование индекса вне этого диапазона является неопределенным поведением.
1) С ++ 14 21.4.5 / 2 о basic_string::operator[]
: «Возвращает: *(begin() + pos)
если pos < size()
, В противном случае возвращает ссылку на объект типа
charT
со значением charT()
где изменение объекта приводит к неопределенному поведению ».
2). С ++ 14 21.4.6 / 5 о basic_string::at
: «Броски: out_of_range
если pos >= size()
”, Где тип индексации без знака.
3) С ++ 14 21.4.5 / 1 о basic_string::operator[]
: «требует: pos <= size
«.