Вопрос о неисправности сегментации
-
19-09-2019 - |
Вопрос
Я заметил, что иногда в программах на языке Си, если у нас есть printf
в коде нигде до ошибки сегментации он не печатается.Почему это так?
Решение
Это потому, что вывод из printf()
буферизуется.Вы могли бы добавить fflush(stdout);
сразу после вашего printf
и это было бы напечатано.
Также вы могли бы сделать это:
fprintf(stderr, "error string");
с тех пор как stderr
не буферизуется.
Другие советы
Если ошибка сегментации возникает слишком скоро после printf, и выходной буфер не был очищен, вы не увидите эффекта printf.
Большинство реализаций libc буферизуют вывод printf.Обычно достаточно добавить новую строку ( ) к выходной строке, чтобы заставить ее очистить содержимое буферов.
Вы можете очистить выходной буфер сразу после printf to, чтобы гарантировать, что это произойдет до сбоя seg.Например.промывка (стандартный вывод)
Случайный совет:если вы пытаетесь устранить ошибки сегментации, обязательно попробуйте валгринд.Это делает все намного проще!
Вам был дан ряд ответов, указывающих на буферизацию выходного потока.
К лучшему это или к худшему, но это далеко не единственная возможность.Ошибка сегментации означает, что операционная система обнаружила, что вы сделали что-то неправильно, обычно записанное за пределами выделенной памяти.К лучшему или к худшему (в основном к худшему), делая почти что угодно в такой ситуации можно изменить достаточно того, что программа делает внутренне, чтобы предотвратить обнаружение проблемы, по крайней мере, в то время / в ситуации, когда она была обнаружена ранее.
Например, ошибка сегмента могла быть вызвана записью через неинициализированный указатель - который случайно содержал определенное значение (возможно, какое-то маленькое целое число), потому что функция, которую вы вызвали ранее, оставила это значение в нужном месте в стеке, и когда более поздняя функция была вызвана и использовала это же значение в качестве указателя, оно (разумно надежно) содержало значение, которое ОС определила как место, в которое вам не разрешалось записывать.Однако выполнение вызова printf может означать, что вы оставляете какое-то совершенно другое значение в том месте стека, которое вы используете без инициализации.Вы все еще пишете там, где не должны, но теперь это может быть где-то, чего ОС не делает знать тебе не следовало бы писать.