Я заметил, что иногда в программах на 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 может означать, что вы оставляете совершенно другое значение на месте в стеке, которое вы используете без инициализации. Вы все еще пишете где-то, чего не следует, но теперь может быть где-то, что ОС не знает, что вы не должны писать.