Почему я не получаю ошибку сегментации, когда пишу за пределами массива?

почему это не дает ошибку при компиляции?

#include  using namespace std; int main() { int *a = new int[2]; // int a[2]; // even this is not giving error a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3; a[100] = 4; int b; return 0; } 

может кто-нибудь объяснить, почему это происходит. Заранее спасибо.)

Я предполагаю, что вы приходите с Java или Java-подобного языка, где, когда вы выходите из границы массива, вы получаете исключение «index index out of bounds».

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

И помните о будущем, что если у вас есть ошибка в вашей программе, и вы не можете ее найти, и когда вы переходите через код / ​​отлаживаете ее, все кажется ОК, есть хороший шанс, что вы «из границ “и доступа к нераспределенному месту.

Потому что неопределенное поведение == все может случиться. Вам не повезло, что это не сбой, такое поведение может потенциально скрывать ошибки.

Что касается a существа дважды – это ошибка в компиляторе.

Объявление двух переменных, называемых конечно, является ошибкой; если ваш компилятор соглашается с этим, тогда он сломан. Я предполагаю, что вы имеете в виду, что вы все равно не получите ошибку, если вы замените одно объявление другим.

Доступ к массиву не проверяется диапазоном. Во время компиляции размер массива часто неизвестен, и язык не требует проверки даже тогда, когда он есть. Во время выполнения проверка снизит производительность, что противоречит философии C ++, которая не платит за то, что вам не нужно. Таким образом, доступ за пределами массива дает неопределенное поведение, и программист должен убедиться, что этого не происходит.

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

Если вы хотите быть в безопасности, вы можете использовать std::vector и получать доступ только к своим элементам с помощью функции at() . Это проверит индекс и выдаст исключение, если оно выходит за пределы допустимого диапазона. Он также будет управлять распределением памяти для вас, исправляя утечку памяти в вашем примере.

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

  • segmentation fault с помощью scanf
  • Ошибка сегментации, большие массивы
  • Ошибка сегментации в glGenVertexArrays (1, & vao);
  • strtok дает ошибку сегментации
  • Окончательный список общих причин сбоев сегментации
  • Interesting Posts

    Уход за регулярными выражениями

    Как использовать имя classа в качестве параметра в C #

    Ограничить количество устройств, которые могут быть сопряжены с устройством Bluetooth?

    Какие счетчики perfmon полезны для выявления узких мест ASP.NET?

    Как обновить графический интерфейс из другого streamа?

    OpenGL не работает в Windows

    Как найти абсолютную позицию щелчка при увеличении

    Как обрабатывать инъекцию зависимостей в приложении WPF / MVVM

    Как создать резервную копию и восстановить системный буфер обмена в C #?

    Полноэкранный Emacs в OSX

    Получение TypeError: __init __ () отсутствует 1 требуемый позиционный аргумент: ‘on_delete’ при попытке добавить родительскую таблицу после дочерней таблицы с записями

    Метод onFrameAvailable () SurfaceTexture всегда называется слишком поздним

    TypeLoadException говорит «нет реализации», но он реализован

    Как скопировать профиль пользователя при изменении доменов?

    Почему Windows 7 запрашивает дополнительные драйверы при установке с USB 3.0?

    Давайте будем гением компьютера.