Почему я не получаю ошибку сегментации, когда пишу за пределами массива?
почему это не дает ошибку при компиляции?
#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; }
может кто-нибудь объяснить, почему это происходит. Заранее спасибо.)
- Ошибка сегментации в реализации btree
- Ошибка сегментации перед основным
- Как уловить ошибку сегментации в Linux?
- Segfaults в malloc () и malloc_consolidate ()
- SegFault после scanf?
- Что может привести к ошибкам сегментации в C ++?
- Ошибка сегментации cudaMemcpy
- Ошибка сегментации при больших размерах массива
- Каков самый простой стандарт, способный создать Segfault в C?
- Что такое segmentation fault?
- Почему java-приложение врезается в gdb, но работает нормально в реальной жизни?
- Почему этот код разворота строки C вызывает ошибку сегментации?
- Ошибка сегментации в strcpy ()
Я предполагаю, что вы приходите с Java или Java-подобного языка, где, когда вы выходите из границы массива, вы получаете исключение «index index out of bounds».
Ну, C ожидает от вас большего; он экономит пространство, которое вы просите, но он не проверяет, выходите ли вы за пределы этого накопленного пространства. Как только вы это сделаете, как указано выше, у программы есть такое страшное неопределенное поведение.
И помните о будущем, что если у вас есть ошибка в вашей программе, и вы не можете ее найти, и когда вы переходите через код / отлаживаете ее, все кажется ОК, есть хороший шанс, что вы «из границ “и доступа к нераспределенному месту.
Потому что неопределенное поведение == все может случиться. Вам не повезло, что это не сбой, такое поведение может потенциально скрывать ошибки.
Что касается a
существа дважды – это ошибка в компиляторе.
Объявление двух переменных, называемых конечно, является ошибкой; если ваш компилятор соглашается с этим, тогда он сломан. Я предполагаю, что вы имеете в виду, что вы все равно не получите ошибку, если вы замените одно объявление другим.
Доступ к массиву не проверяется диапазоном. Во время компиляции размер массива часто неизвестен, и язык не требует проверки даже тогда, когда он есть. Во время выполнения проверка снизит производительность, что противоречит философии C ++, которая не платит за то, что вам не нужно. Таким образом, доступ за пределами массива дает неопределенное поведение, и программист должен убедиться, что этого не происходит.
Иногда недопустимый доступ вызывает ошибку сегментации, но это не гарантируется. Как правило, защита памяти применяется только к целым страницам памяти с типичным размером страницы в несколько килобайт. Любой доступ на странице действительной памяти не будет обнаружен. Существует хорошая вероятность того, что доступная вам память содержит некоторую другую программную переменную или часть стека вызовов, поэтому запись может повлиять на поведение программы практически так, как вы можете себе представить.
Если вы хотите быть в безопасности, вы можете использовать std::vector
и получать доступ только к своим элементам с помощью функции at()
. Это проверит индекс и выдаст исключение, если оно выходит за пределы допустимого диапазона. Он также будет управлять распределением памяти для вас, исправляя утечку памяти в вашем примере.
компиляторы с хорошим анализом кода, безусловно, будут предупреждать о том, что код ссылается за пределы распределения массива. забыв о множественном объявлении, если вы его запустили, он может или не может быть неисправен (неопределенное поведение, как говорили другие). если, например, у вас есть страница с кучей на 4 Кбайт (в адресном пространстве процессора), если вы не пишете вне этой страницы, вы не получите ошибку от процессора. после удаления массива, если вы это сделали, и в зависимости от реализации кучи куча может обнаружить, что она повреждена.