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?
Там с любых версий адресация была виртуальной или как?