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

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

10 голосов
/ 04 октября 2009

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

Ответы [ 6 ]

20 голосов
/ 04 октября 2009

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

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

fprintf(stderr, "error string");

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

Есть также связанный вопрос .

5 голосов
/ 04 октября 2009

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

5 голосов
/ 04 октября 2009

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

3 голосов
/ 04 октября 2009

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

3 голосов
/ 04 октября 2009

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

0 голосов
/ 04 октября 2009

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

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

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

...