В каких именно случаях C генерирует ошибку сегментации? - PullRequest
0 голосов
/ 24 октября 2019

Я знаю, что в случае доступа к массивам за пределами:

int arr[2]; 
arr[3] = 10;

C выдаст Segmentation fault (core dumped) во время выполнения.

Однако C не выходит за пределыдоступ с другими вещами, такими как strcpy().

Я хочу точно знать, какие случаи могут вызвать ошибку сегментации, а какие нет.

Ответы [ 2 ]

0 голосов
/ 24 октября 2019

Доступ к любой памяти, которой вы не владеете, является неопределенным поведением. Это просто означает, что стандарт C вообще ничего не требует от компилятора, чтобы справиться с ситуацией.

Поскольку C стремится быть эффективным языком, компиляторы редко (когда-либо?) Будут выпускать машинный код, который обеспечиваетпроверки во время выполнения таких вещей. Они могут выдавать или не выдавать предупреждения или ошибки, если нарушение обнаруживается во время компиляции.

Суть этого заключается в следующем: любое сообщение об ошибке, включая segfault, которое вы получаете во время выполнения, обычно исходит изОПЕРАЦИОННЫЕ СИСТЕМЫ. На старых системах / ОС или даже сегодня на небольших (встроенных) системах такого рода управление памятью было / не было доступно, и нарушения доступа к памяти могли просто привести к сбою всей системы, возможно, в течение длительного времени после первоначального нарушения. Или ничего не могло случиться. Или даже более коварные вещи, такие как повреждение данных.

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

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

Кстати: как заметил Селби в комментарии, ваш код, вероятно, перезаписывает часть стекового фрейма функции или записи активации. Причина этого в том, что стек на большинстве машин растет вниз (новая память выделяется по меньшим адресам), но индексация массива движется вверх. Многие компиляторы включают опцию компиляции с помощью «стека канарейки», который может обнаружить повреждение стека во время выполнения. Это очень полезная функция при разработке и тестировании, а также обеспечивает некоторую защиту от вредоносных программ, которые пытаются использовать именно такие переполнения буфера.

0 голосов
/ 24 октября 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...