Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/12: Рейтинг темы: голосов - 12, средняя оценка - 4.67
║XLR8║
1041 / 830 / 254
Регистрация: 25.07.2009
Сообщений: 4,121
Записей в блоге: 5
1

out_of_range exaptions и условные операторы

26.02.2011, 21:43. Просмотров 2164. Ответов 17
Метки нет (Все метки)

Меня интересует следущее: почему этот код не выдает ошибок типа "индекс вне границ массива"
C++
1
if (a[i] > 0) something();
Работа этого кода при превышении границ массива похожа на
C++
1
if (false) something();
Кто-то может обьяснить почему так происходит? Я из-за этого на topcoder-e 4 challenge-a завалил.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.02.2011, 21:43
Ответы с готовыми решениями:

Решение неравенства используя условные операторы
Помогите,пожалуйста,написать программу.В DevC++.

Вычисления и условные операторы
Разместить на форме 2 компонента Edit для ввода роста и веса пользователя. При нажатии на кнопку...

Арифметические выражения и условные операторы
С помощью условного оператора определить, находится ли точка на плоскости в замкнутой области....

Условные операторы: определить, какой день недели выпадает на заданное число
Дано трехзначное число от 1 до 365. Определить, какой день недели выпадает на это число, если 1...

17
2 / 2 / 1
Регистрация: 23.02.2011
Сообщений: 13
26.02.2011, 21:50 2
Всё очень просто: массив в С - это последовательность указателей на нечто типа элементов массива, поэтому при превышении границ диапазона указатель становится "битым" (
C
1
nullptr
), его значение становится эквивалентным нулю (
C
1
false
). Если бы Вы проверяли
C
1
if (a[i]) something();
, то компилятор выдавал бы исключение по выходу за диапазон, а так это ловится только при отладке
1
║XLR8║
1041 / 830 / 254
Регистрация: 25.07.2009
Сообщений: 4,121
Записей в блоге: 5
26.02.2011, 21:55  [ТС] 3

Не по теме:

Во блин, на "человеческом" C# вываливается за милую душу, а на плюсах пашет ппц (:



Добавлено через 1 минуту
Значит код
C++
1
Type a = b[i];
при превышении диапазона будет вываливаться верно?
0
1992 / 1592 / 488
Регистрация: 31.05.2009
Сообщений: 2,980
26.02.2011, 22:39 4
Ни в С, ни в C++ выход за границы простого массива не контролируется. За этим нужно следить самостоятельно. Для таких контейнеров как std::vector и std::string контроль выхода за границы массива при обращении к элементам через operator[] также не осуществляется, для этих целей используется специальный метод at. Вот этот метод как раз и выбрасывает исключение out_of_range.
1
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
27.02.2011, 01:51 5
Для таких контейнеров как std::vector и std::string контроль выхода за границы массива при обращении к элементам через operator[] также не осуществляется
Зависит от реализации STL. По стандарту - разрешается, но не везде есть. Пример - MSVS реализация [] в векторе
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    const_reference operator[](size_type _Pos) const
        {   // subscript nonmutable sequence
 
 #if _HAS_ITERATOR_DEBUGGING
        if (size() <= _Pos)
            {
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
 #endif /* _HAS_ITERATOR_DEBUGGING */
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());
 
        return (*(_Myfirst + _Pos));
        }
 
    reference operator[](size_type _Pos)
        {   // subscript mutable sequence
 
 #if _HAS_ITERATOR_DEBUGGING
        if (size() <= _Pos)
            {
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
 #endif /* _HAS_ITERATOR_DEBUGGING */
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());
 
        return (*(_Myfirst + _Pos));
        }
0
1992 / 1592 / 488
Регистрация: 31.05.2009
Сообщений: 2,980
27.02.2011, 02:09 6
Цитата Сообщение от ForEveR Посмотреть сообщение
По стандарту - разрешается, но не везде есть.
Ссылку на соответствующее место в стандарте неплохо бы увидеть.
Цитата Сообщение от ForEveR Посмотреть сообщение
Пример - MSVS реализация [] в векторе
И это будет работать в релизе?
0
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
27.02.2011, 03:04 7
rangerx,
C++
1
 _SCL_SECURE_VALIDATE_RANGE(_Pos < size());
Это бyдет.
Ссыль приведy по3же. Рykоводствyюсь Страyстрyпом. Цитата.
На самом деле стандарт не утверждает, что вы не можете проверить диапазон в классе вектор, поэтому если хотите выполнить проверку, можете ее реализовать...
И еще есть пара пунктов по этому поводу, но лень все переписывать...

Добавлено через 38 минут
Подтверждений в стандарте не нашел, но Страуструпу верю.
0
1992 / 1592 / 488
Регистрация: 31.05.2009
Сообщений: 2,980
27.02.2011, 03:10 8
Цитата Сообщение от ForEveR Посмотреть сообщение
Это бyдет.
К сожалению у меня нет возможности сейчас это проверить, поэтому придётся поверить тебе на слово. )
Цитата Сообщение от ForEveR Посмотреть сообщение
Страyстрyпом. Цитата.
Ну хоть бы на Страуструпа дал ссылку ) Специально открыл только что "Язык программирования C++. Специальное издание" $16.3.3. Доступ к элементам и вижу там то же самое, что сказал я. В любом случае, никакой гарантии, что operator[] осуществит проверку выхода за диапазон нет. "На самом деле стандарт не утверждает..." - это не серъёзно. ))
0
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
27.02.2011, 03:25 9
rangerx, Ну естесно) Все зависит от реализации. Ссылки на книгу боюсь нету на русском языке еще, а может уже и есть. Программирование принципы и практика использования С++ - страница 698, пункт 19.4.1, подпункт 4.

Про MSVS - такой код в релизе
C++
1
2
3
4
5
6
7
#include <vector>
 
int main()
{
    std::vector<int> vec(10);
    int t=vec[10];
}
Кидает runtime_error
0
║XLR8║
1041 / 830 / 254
Регистрация: 25.07.2009
Сообщений: 4,121
Записей в блоге: 5
27.02.2011, 09:38  [ТС] 10
ForEveR, а такой:
C++
1
    int t=vec[10] < 0 ? 0 : vec[10];
0
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
27.02.2011, 15:52 11
outoftime, Вылетит. Очевидно почему. vec[10] читает какую-то другую область памяти.
0
║XLR8║
1041 / 830 / 254
Регистрация: 25.07.2009
Сообщений: 4,121
Записей в блоге: 5
27.02.2011, 16:19  [ТС] 12
ForEveR, результаты последнего SRM на TopCoder-е, посмотрите пожалуйста, есть солюшены и тесты, на которых я их хотел слить, что касается C# и Java, опять таки, там все слетели, но кто писал на плюсах и ставил в условные операторы, впрочем, смотрите сами.

http://www.topcoder.com/stat?c... 3#defenses
http://www.topcoder.com/stat?c... 9#defenses
http://www.topcoder.com/stat?c... 9#defenses

Что обьеденяет эти коды, если мы подаем вектор {50} с 1 элементом и какая разница с этим

http://www.topcoder.com/stat?c... 3#defenses

Добавлено через 4 минуты
Имеется в виду на вход метода isValid (если вы не знакомы с правилами)
0
1992 / 1592 / 488
Регистрация: 31.05.2009
Сообщений: 2,980
27.02.2011, 19:09 13
Цитата Сообщение от ForEveR Посмотреть сообщение
Все зависит от реализации.
Ну, может быть, не буду спорить. В стандарте скорее всего вообще об этом ничего не говорится.
Цитата Сообщение от outoftime Посмотреть сообщение
а такой:
Если повезёт...
0
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
27.02.2011, 19:11 14
В стандарте скорее всего вообще об этом ничего не говорится.
Ага. Читая стандарт по контейнерам вчера увидел только про то, что at() обязана гарантировать проверку на диапазон.
0
║XLR8║
1041 / 830 / 254
Регистрация: 25.07.2009
Сообщений: 4,121
Записей в блоге: 5
27.02.2011, 19:18  [ТС] 15
Цитата Сообщение от rangerx Посмотреть сообщение
В стандарте скорее всего вообще об этом ничего не говорится.
Цитата Сообщение от ForEveR Посмотреть сообщение
Ага. Читая стандарт по контейнерам вчера увидел только про то, что at() обязана гарантировать проверку на диапазон.
Это что получается то? Когда я вижу что-то типа:
C++
1
if (a[i] > 0) something();
я должен считать что он правильный? На случай если релиз позволяет? Не знаете что говорит об этом gcc именно его юзает topcoder.
0
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
27.02.2011, 19:20 16
outoftime, Используй at() и будет тебе счастье.
А лучше итераторы. имхо)
0
1992 / 1592 / 488
Регистрация: 31.05.2009
Сообщений: 2,980
27.02.2011, 19:30 17
Цитата Сообщение от outoftime Посмотреть сообщение
Не знаете что говорит об этом gcc
C++
1
2
3
4
5
6
7
8
9
10
11
reference operator[](size_type __n)
{ 
    return *(begin() + __n); 
}
 
//---------
 
const_reference operator[](size_type __n) const
{ 
    return *(begin() + __n); 
}
1
║XLR8║
1041 / 830 / 254
Регистрация: 25.07.2009
Сообщений: 4,121
Записей в блоге: 5
27.02.2011, 19:39  [ТС] 18
Цитата Сообщение от ForEveR Посмотреть сообщение
Используй at() и будет тебе счастье.
А лучше итераторы. имхо)
Да я такие ляпы заметаю, мне надо знать когда это неправильно у других (:
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.02.2011, 19:39

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Типы данных. Операции. Операторы. операторы ветвления
Создать программу. Воспользоваться оператором вариантов. ...

С++.Операторы в С++: условные операторы, операторы break и continue
Выяснить, пересекаются ли параболы у=аx2+bx+с и у=dx2+ex + f. При положительном ответе найти точки...

Условные операторы и операторы цикла, проверка корректности вводимых данных
Привет, ребята. Помогите, пожалуйста, написать код для данной задачи. Примечание: необходимо...

«Языки и технологии программирования» «Операторы цикла. Условные операторы»
Не получается сделать что бы программа выводила все значения в промежутке, она выводит только одно....


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

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

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