Что такое выход за границы массива почему он может быть опасен
Перейти к содержимому

Что такое выход за границы массива почему он может быть опасен

C++: выход за пределы массива

В разной литературе по C/C++ говорится, что выход за пределы статических и динамических массивов не проверяется компилятором. При попытке записать данные за границу массива будет получена ошибка сегментации при выполнении программы.

Но это не всегда так. Приведу два интересных примера.

Первый пример:
int main()
<
int* a = new int[9];
a[10] = 777;
int* b = new int;
std::cout << *b << std::endl;
return 0;
>

Выделив память на целочисленный массив а из девяти элементов, мы записываем одиннадцатому элементу значение 777. Затем выделяем память под указатель на int (она выделяется не сразу после массива a, а через 1 байт). Выполняем программу и видим на экране 777. При выполнении программы не произошло ошибки сегментации, что является настораживающим фактором для программиста.

Второй пример

int main()
<
int a[5];
a[900] = 777;
std::cout << a[900] << std::endl;
return 0;
>

На этот раз объявим статический массив из пяти элементов, и присвоим 901ому элементу значение 777. Выводим это значение на экран. Запустим получившуюся программу несколько раз подряд:

/prog/cpp/test$ ./a.out
777
nathan@eeepc:

/prog/cpp/test$ ./a.out
777
nathan@eeepc:

/prog/cpp/test$ ./a.out
777
nathan@eeepc:

/prog/cpp/test$ ./a.out
777
nathan@eeepc:

/prog/cpp/test$ ./a.out
Ошибка сегментирования
nathan@eeepc:

/prog/cpp/test$ ./a.out
777
nathan@eeepc:

/prog/cpp/test$ ./a.out
777

Как видим, в большинстве случаев программа срабатывает, и при отладке программист может посчитать что программа рабочая. Но в реальных условиях при многократном запуске могут появляться проблемы, которые потом программисту будет трудно устранять.

К чему я это все написал: при разработке программного обеспечения уделяйте большое внимание работе с индексами массивов(указателей), не ленитесь многократно проверять код, чтобы избежать трудноразрешимых, непонятно откуда взявшихся ошибок.

Проверка существования значения — JS: Массивы

При работе с массивами часто допускается ситуация, называемая "выход за границу массива". Она возникает при обращении к несуществующему индексу:

В разных языках программирования поведение в случае выхода за границу реализовано совершенно по-разному. Иногда возникает ошибка, иногда нет, а иногда подобный выход возвращает случайные данные из соседнего блока памяти, как в Си, что может привести к катастрофе.

В JavaScript свой путь. Здесь дана большая свобода, допускающая почти любые вольности. Обращение по несуществующему индексу возвращает значение undefined . При этом никаких ошибок не возникает, это рассматривается как нормальная ситуация:

В подавляющем большинстве ситуаций, выход за границу массива является нежелательным поведением. Он происходит из-за логических ошибок в программе. Программа, при этом, продолжает работать и, даже, иногда выдавать правильный результат. Самый простой способ проверить выход за границу, это убедиться в том что индекс не превышает длину массива:

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

Что такое выход за границы массива почему он может быть опасен

В своей книге, Герберт Шилдт утверждает, что ввод данных за границу массива может привести к плачевным результатам не только для программы, но и для всей ОС.

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

Я понимаю это так : Если я выйду за границу массива, то есть шанс того, что я невольно разрушу/изменю значения своих других переменных в своей программе.

Отсюда у меня возникает три вопроса.
1) Правильно-ли я все понял?

2) А что будет, если я выйду за границу массива, но его граница будет являться последним зарезервированным адресом в памяти для моей программы, что произойдет в таком случае?
Пример:

3) Если в Windows адресация стала виртуальной только с Windows 2000(включительно), то как дело обстоит в UNIX системах?
К примеру, в Linux или BSD?
Там с любых версий адресация была виртуальной или как?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *