【发布时间】:2010-12-03 16:24:59
【问题描述】:
我观察到,有时在 C 程序中,如果在分段错误之前的代码中有 printf,它不会打印。为什么会这样?
【问题讨论】:
-
我经常看到非英语母语人士使用“我对……有疑问”这个短语。我不希望看到以英语为母语的人开始不恰当地使用“怀疑”这个词。
标签: c io segmentation-fault unbuffered-output
我观察到,有时在 C 程序中,如果在分段错误之前的代码中有 printf,它不会打印。为什么会这样?
【问题讨论】:
标签: c io segmentation-fault unbuffered-output
这是因为printf() 的输出被缓冲了。您可以在printf 之后立即添加fflush(stdout);,它会打印出来。
你也可以这样做:
fprintf(stderr, "error string");
因为stderr 没有被缓冲。
【讨论】:
如果在 printf 之后太快出现分段错误,并且输出缓冲区没有刷新,您将看不到 printf 的效果。
【讨论】:
大多数 libc 实现缓冲 printf 输出。通常将换行符 (\n) 附加到输出字符串以强制它刷新缓冲区内容就足够了。
【讨论】:
您可以在 printf 之后立即刷新输出缓冲区,以确保它会在段错误之前发生。例如。 fflush(标准输出)
【讨论】:
随机提示:如果您尝试调试分段错误,请务必尝试valgrind。它使它变得更容易!
【讨论】:
您已经获得了许多关于输出流缓冲的答案。
无论好坏,这远非唯一的可能性。分段错误意味着操作系统检测到您做错了什么,通常写在分配的内存之外。在这种情况下,无论好坏(大多数情况下),几乎任何事情都可以改变程序内部所做的足够多的事情,以防止问题被检测到,至少在它发生的时间/情况下之前检测到。
例如,段错误可能是由未初始化的指针写入引起的——该指针恰好保存了某个值(可能是一些小整数),因为您之前调用的函数将该值留在了正确的位置当调用后面的函数并使用与指针相同的值时,堆栈(相当可靠)包含操作系统检测为您不允许写入的位置的值。然而,调用 printf 可能意味着您在堆栈上的某个位置留下了一些完全不同的值,而这些值是您在没有初始化的情况下使用的。你仍在写你不应该写的地方,但它现在可能是操作系统不知道的地方知道你不应该写。
【讨论】: