исключение out_of_range со строками

Я пытался понять 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

Решение

Это потому, что оператор [] ничего не проверяет, а at () делает. CppReference говорит:

станд :: basic_string :: на

Возвращает ссылку на символ в указанном месте поз. Проверка границ выполняется, исключение типа std :: out_of_range будет выдано при недопустимом доступе.

станд :: basic_string :: Оператор []

Возвращает ссылку на символ в указанном месте поз. Проверка границ не выполняется.

1

Другие решения

std::string::at а также std::string::operator[] работать по-другому.

  • at(size_t) Метод проверяет текущий размер строки: если она выходит за границы — она ​​выдаст исключение.

  • operator[](size_t) это прямой доступ к куску памяти. Так что проблема будет во время выполнения.

станд :: строка :: оператор []

станд :: строка :: на

1

Со строкой 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«.

1
По вопросам рекламы [email protected]