Форум программистов, компьютерный форум CyberForum.ru

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

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

C++ Подскажите почему происходит ошибка в вычислении
C++ Ошибка при обращении к элементу строки *s
C++ Почему происходит ошибка при описании массива?
C++ Ошибка при обращении к методу константного объекта
C++ При обращении к структуре из класса возникает исключение:нарушение прав доступа при записи. Почему?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,898
Завершенные тесты: 1
28.06.2010, 10:36     Почему не происходит ошибка при обращении к недопустимому индексу #2
Оператор индексации [] в STL проектируется так, чтобы не отставать от обычной индексации по скорости. То есть, он не проверяет передаваемые ему индексы и не выбрасывает исключения. Этим занимается at(). Так что я склоняюсь ко второму варианту из предложенных.
Хохол
Эксперт C++
 Аватар для Хохол
475 / 443 / 13
Регистрация: 20.11.2009
Сообщений: 1,292
28.06.2010, 10:50  [ТС]     Почему не происходит ошибка при обращении к недопустимому индексу #3
Оператор [] всю жизнь все проверял и выбрасывал исключения. s[1] в данном примере выбрасывает исключение.

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

Добавлено через 2 минуты
Попробуйте запустить этот код у себя.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,898
Завершенные тесты: 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'ом, которая включается только при компиляции в отладочном режиме.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
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
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,898
Завершенные тесты: 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
Хохол
Эксперт C++
 Аватар для Хохол
475 / 443 / 13
Регистрация: 20.11.2009
Сообщений: 1,292
28.06.2010, 15:59  [ТС]     Почему не происходит ошибка при обращении к недопустимому индексу #7
А почему ж на кодпаде мой код фейлится?

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

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

Ну и мы видим, что на кодепаде таки в отладочную конфигурацию компилируют, чтобы с дополнительными проверками. И в режиме pedantic.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.12.2012, 13:03     Почему не происходит ошибка при обращении к недопустимому индексу #9
Цитата Сообщение от Nick Alte Посмотреть сообщение
Как видим, есть только проверка assert'ом, которая включается только при компиляции в отладочном режиме.
Но всё таки проверка есть, а режим мог быть и отладочный.

Добавлено через 3 минуты
Вот только при индексации с ноля <=size даст допустимость индекса сразу за концом строки. Видимо данная реализация std::string хранит на один символ больше, чем длина строки и реально последний символ всегда терминальный ноль. Тогда исключение на [0] и не должно выскакивать, так как в любой, даже пустой, строке всегда будет как минимум один символ, так как терминальный ноль - тоже символ и он есть в каждой, даже пустой, строке.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.12.2012, 09:58     Почему не происходит ошибка при обращении к недопустимому индексу
Еще ссылки по теме:

Разница в обращении к массиву по индексу и по указателю C++
C++ При обращении к индексу двумерного массива char программа вылетает с ошибкой
C++ Ошибка при обращении к статическому члену

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

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
29.12.2012, 09:58     Почему не происходит ошибка при обращении к недопустимому индексу #10
taras atavin, это зависит не от того, что строка там хранит. Она может изначально хоть "Hello, World!" хранить, но пока в неё что-то не записано, размер у неё 0. И поэтому оператор индексации, если бы он должен был выбрасывать исключение, выбросил бы его. Но по стандарту оператор индексации работает без проверок, метод at() - с проверками.
Yandex
Объявления
29.12.2012, 09:58     Почему не происходит ошибка при обращении к недопустимому индексу
Ответ Создать тему
Опции темы

Текущее время: 09:40. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru