Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Хохол
Эксперт С++
475 / 443 / 34
Регистрация: 20.11.2009
Сообщений: 1,293
1

Почему не происходит ошибка при обращении к недопустимому индексу

27.06.2010, 22:46. Просмотров 871. Ответов 9
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
#include <string>
 
int main()
{
    std::string s;
    s[0];
}
Исключения не происходит. Внимание вопрос: я схожу с ума, я не знаю цпп или мне нагло врет VS?
Думаю, все же третье. Никогда раньше такого не встречал. При обращении к s[1] исключение исправно выбрасывается.
Запускаю в VS 2008. Может кто знает, что за фигня?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.06.2010, 22:46
Ответы с готовыми решениями:

При обращении к индексу двумерного массива char программа вылетает с ошибкой
Программа вылетает с ошибкой на 66й строке. Почему?((( // Task_1.cpp : Defines the entry point for...

Почему происходит ошибка при описании массива?
int setSize; cout &lt;&lt; &quot;How many elements would you have? &quot;; cin &gt;&gt; setSize; const int getSize...

Разница в обращении к массиву по индексу и по указателю
Дочитал до главы &quot;Указатели&quot; и возникли вопросы, если у кого найдется время подскажите Вот...

При обращении к структуре из класса возникает исключение:нарушение прав доступа при записи. Почему?
Структура Test описана в классе ABC: class ABC{ struct Test { int get_i() { return i; }...

Почему при обращении по индексу к массиву с модификатором readonly мы можем записывать значение
Народ объясните новичку почему при обращении по индексу к массиву с модификатором readonly мы...

9
Nick Alte
Эксперт С++
1653 / 1025 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
28.06.2010, 10:36 2
Оператор индексации [] в STL проектируется так, чтобы не отставать от обычной индексации по скорости. То есть, он не проверяет передаваемые ему индексы и не выбрасывает исключения. Этим занимается at(). Так что я склоняюсь ко второму варианту из предложенных.
0
Хохол
Эксперт С++
475 / 443 / 34
Регистрация: 20.11.2009
Сообщений: 1,293
28.06.2010, 10:50  [ТС] 3
Оператор [] всю жизнь все проверял и выбрасывал исключения. s[1] в данном примере выбрасывает исключение.

Добавлено через 2 минуты
http://codepad.org/bC2VIMF6

Добавлено через 2 минуты
Попробуйте запустить этот код у себя.
0
Nick Alte
Эксперт С++
1653 / 1025 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
28.06.2010, 15:20 4
Документация на STL утверждает иное. И уж извините, Хохол, но в этом вопросе я скорее доверюсь документации.
Код из basic_string.h библиотеки из состава GCC:
C++
1
2
3
4
5
const_reference operator[] (size_type __pos) const
{
    _GLIBCXX_DEBUG_ASSERT(__pos <= size());
    return _M_data()[__pos];
}
Как видим, есть только проверка assert'ом, которая включается только при компиляции в отладочном режиме.
1
28.06.2010, 15:20
easybudda
Модератор
Эксперт JavaЭксперт CЭксперт С++
10297 / 6179 / 1555
Регистрация: 25.07.2009
Сообщений: 11,762
28.06.2010, 15:52 5
Цитата Сообщение от Хохол Посмотреть сообщение
Исключения не происходит.
да вроде и не должно бы. При создании объекта класса string как минимум один элемент в нём уже присутствует (тот самый, на который итератор возвращаемый функцией end() указывает), вот Вам и s[0], а вот s[1] и в правду нету, потому и исключение...
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>
 
int main(){
    std::string s;
    char c;
    c = s[0];
    std::cout << (int)c << std::endl;
    
    return 0;
}
выведет 0
1
Nick Alte
Эксперт С++
1653 / 1025 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
28.06.2010, 15:55 6
На всякий случай напомню всем, кто заинтересуется: на пару к оператору индексации в индексируемых STL-контейнерах добавляют функцию at(), которая делает то же самое, но индекс как раз-таки проверяет и std::out_of_range выбрасывает в случае чего.
Так что код
C++
1
2
3
4
5
6
#include <string>
int main()
{
        std::string s;
        s.at(0);
}
выбросит то самое исключение std::out_of_range
0
Хохол
Эксперт С++
475 / 443 / 34
Регистрация: 20.11.2009
Сообщений: 1,293
28.06.2010, 15:59  [ТС] 7
А почему ж на кодпаде мой код фейлится?

Добавлено через 28 секунд
А у них ассерт другой почему-то
Код
Assertion '__pos < size()' failed.
1
Nick Alte
Эксперт С++
1653 / 1025 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
28.06.2010, 16:13 8
А у них вполне могла бы быть и реализация STL другая. Стандарт предъявляет только определённые требования к поведению, а уж реализуются они у кого как. В Visual Studio будет другой ассерт.

Тем не менее, ассерт как раз тот же самый. В тексте библиотеки упоминается следующее:
// allow pos == size() as v3 extension
(допустить равенство pos и size() в качестве расширения v3)
В режиме pedantic в неконстантном индексировании используется строгое сравнение pos < size(), которое мы и видим в кодепадовском сообщении.

Ну и мы видим, что на кодепаде таки в отладочную конфигурацию компилируют, чтобы с дополнительными проверками. И в режиме pedantic.
0
taras atavin
4207 / 1774 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.12.2012, 13:03 9
Цитата Сообщение от Nick Alte Посмотреть сообщение
Как видим, есть только проверка assert'ом, которая включается только при компиляции в отладочном режиме.
Но всё таки проверка есть, а режим мог быть и отладочный.

Добавлено через 3 минуты
Вот только при индексации с ноля <=size даст допустимость индекса сразу за концом строки. Видимо данная реализация std::string хранит на один символ больше, чем длина строки и реально последний символ всегда терминальный ноль. Тогда исключение на [0] и не должно выскакивать, так как в любой, даже пустой, строке всегда будет как минимум один символ, так как терминальный ноль - тоже символ и он есть в каждой, даже пустой, строке.
0
silent_1991
Эксперт С++
5016 / 3076 / 271
Регистрация: 11.11.2009
Сообщений: 7,045
Завершенные тесты: 1
29.12.2012, 09:58 10
taras atavin, это зависит не от того, что строка там хранит. Она может изначально хоть "Hello, World!" хранить, но пока в неё что-то не записано, размер у неё 0. И поэтому оператор индексации, если бы он должен был выбрасывать исключение, выбросил бы его. Но по стандарту оператор индексации работает без проверок, метод at() - с проверками.
0
29.12.2012, 09:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.12.2012, 09:58

При попытке удалить строку по индексу имени столбца происходит ошибка
Как подобное можно реализовать? foreach (var n in fclass) { ...

Почему ошибка при обращении к базе данных ?
Помогите пожалуйста запустить сервлет. Сервлет генерирует после запуска из под Tomcate 4.0...

Не срабатывает событие при обращении к кнопке по индексу
Почему не срабатывает событие? Private Sub ListBox1_SelectedIndexChanged(ByVal sender As...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru