Вопрос об ошибке сегментации

Я заметил, что иногда в программах на C, если у нас есть printf в коде где-нибудь перед ошибкой сегментации, он не печатает. Почему это так?

Ответ 1

Это потому, что вывод из printf() буферизуется. Вы можете добавить fflush(stdout); сразу после вашего printf и распечатать.

Также вы можете сделать это:

fprintf(stderr, "error string");

поскольку stderr не буферизируется.

Также есть связанный с этим вопрос.

Ответ 2

Если ошибка сегментации происходит слишком быстро после printf, а выходной буфер не был сброшен, вы не увидите эффект printf.

Ответ 3

Большинство выходных данных буфера печати libc. Обычно этого достаточно, чтобы добавить новую строку (\n) в выходную строку, чтобы заставить ее сбросить содержимое буферов.

Ответ 4

Вы можете сбросить выходной буфер сразу после printf, чтобы убедиться, что это произойдет до сбоя seg. Например. fflush (стандартный вывод)

Ответ 5

Случайный совет: если вы пытаетесь отладить ошибки сегментации, не забудьте попробовать valgrind. Это делает его намного проще!

Ответ 6

Вам задан ряд ответов, указывающих на буферизацию выходного потока.

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

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