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

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.86
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
#1

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

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

Меня интересует следущее: почему этот код не выдает ошибок типа "индекс вне границ массива"
C++
1
if (a[i] > 0) something();
Работа этого кода при превышении границ массива похожа на
C++
1
if (false) something();
Кто-то может обьяснить почему так происходит? Я из-за этого на topcoder-e 4 challenge-a завалил.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.02.2011, 21:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос out_of_range exaptions и условные операторы (C++):

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

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

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

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

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

«Языки и технологии программирования» «Операторы цикла. Условные операторы» - C++
Не получается сделать что бы программа выводила все значения в промежутке, она выводит только одно. условия | ((z^3)+sin...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
АХ
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
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
26.02.2011, 21:55  [ТС] #3

Не по теме:

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



Добавлено через 1 минуту
Значит код
C++
1
Type a = b[i];
при превышении диапазона будет вываливаться верно?
0
rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,912
26.02.2011, 22:39 #4
Ни в С, ни в C++ выход за границы простого массива не контролируется. За этим нужно следить самостоятельно. Для таких контейнеров как std::vector и std::string контроль выхода за границы массива при обращении к элементам через operator[] также не осуществляется, для этих целей используется специальный метод at. Вот этот метод как раз и выбрасывает исключение out_of_range.
1
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
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
rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,912
27.02.2011, 02:09 #6
Цитата Сообщение от ForEveR Посмотреть сообщение
По стандарту - разрешается, но не везде есть.
Ссылку на соответствующее место в стандарте неплохо бы увидеть.
Цитата Сообщение от ForEveR Посмотреть сообщение
Пример - MSVS реализация [] в векторе
И это будет работать в релизе?
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
27.02.2011, 03:04 #7
rangerx,
C++
1
 _SCL_SECURE_VALIDATE_RANGE(_Pos < size());
Это бyдет.
Ссыль приведy по3же. Рykоводствyюсь Страyстрyпом. Цитата.
На самом деле стандарт не утверждает, что вы не можете проверить диапазон в классе вектор, поэтому если хотите выполнить проверку, можете ее реализовать...
И еще есть пара пунктов по этому поводу, но лень все переписывать...

Добавлено через 38 минут
Подтверждений в стандарте не нашел, но Страуструпу верю.
0
rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,912
27.02.2011, 03:10 #8
Цитата Сообщение от ForEveR Посмотреть сообщение
Это бyдет.
К сожалению у меня нет возможности сейчас это проверить, поэтому придётся поверить тебе на слово. )
Цитата Сообщение от ForEveR Посмотреть сообщение
Страyстрyпом. Цитата.
Ну хоть бы на Страуструпа дал ссылку ) Специально открыл только что "Язык программирования C++. Специальное издание" $16.3.3. Доступ к элементам и вижу там то же самое, что сказал я. В любом случае, никакой гарантии, что operator[] осуществит проверку выхода за диапазон нет. "На самом деле стандарт не утверждает..." - это не серъёзно. ))
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
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
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
27.02.2011, 09:38  [ТС] #10
ForEveR, а такой:
C++
1
    int t=vec[10] < 0 ? 0 : vec[10];
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
27.02.2011, 15:52 #11
outoftime, Вылетит. Очевидно почему. vec[10] читает какую-то другую область памяти.
0
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
27.02.2011, 16:19  [ТС] #12
ForEveR, результаты последнего SRM на TopCoder-е, посмотрите пожалуйста, есть солюшены и тесты, на которых я их хотел слить, что касается C# и Java, опять таки, там все слетели, но кто писал на плюсах и ставил в условные операторы, впрочем, смотрите сами.

http://www.topcoder.com/stat?c=probl...24373#defenses
http://www.topcoder.com/stat?c=probl...00369#defenses
http://www.topcoder.com/stat?c=probl...10589#defenses

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

http://www.topcoder.com/stat?c=probl...86983#defenses

Добавлено через 4 минуты
Имеется в виду на вход метода isValid (если вы не знакомы с правилами)
0
rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,912
27.02.2011, 19:09 #13
Цитата Сообщение от ForEveR Посмотреть сообщение
Все зависит от реализации.
Ну, может быть, не буду спорить. В стандарте скорее всего вообще об этом ничего не говорится.
Цитата Сообщение от outoftime Посмотреть сообщение
а такой:
Если повезёт...
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
27.02.2011, 19:11 #14
В стандарте скорее всего вообще об этом ничего не говорится.
Ага. Читая стандарт по контейнерам вчера увидел только про то, что at() обязана гарантировать проверку на диапазон.
0
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
27.02.2011, 19:18  [ТС] #15
Цитата Сообщение от rangerx Посмотреть сообщение
В стандарте скорее всего вообще об этом ничего не говорится.
Цитата Сообщение от ForEveR Посмотреть сообщение
Ага. Читая стандарт по контейнерам вчера увидел только про то, что at() обязана гарантировать проверку на диапазон.
Это что получается то? Когда я вижу что-то типа:
C++
1
if (a[i] > 0) something();
я должен считать что он правильный? На случай если релиз позволяет? Не знаете что говорит об этом gcc именно его юзает topcoder.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.02.2011, 19:18
Привет! Вот еще темы с ответами:

Условные операторы.Операторы цикла - C++
1)По номеру y(y&gt;0) некоторого года определить с-номер его столетия(учесть что к примеру началом 20 столетия был 1901 а не 1900 год.)...

Условные операторы - C++
Написать программу, которая вычисляет дату следующего дня. Ниже представлен рекомендуемый вид экрана во время работы программы. Введите...

Условные операторы - C++
Напечатать таблицу значений функций y=sqr(x)+4x на интервале от -5 до 5.

Условные операторы - C++
Задание: создайте условный оператор, который присваивал бы x*y для четного x, в противном случае для нечетного x и y, не равного 0,...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
27.02.2011, 19:18
Ответ Создать тему
Опции темы

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