views:

360

answers:

6

I have observed that sometimes in C programs, if we have a printf in code anywhere before a segmentation fault, it does not print. Why is it so?

+15  A: 

It's because the output from printf() is buffered. You could add fflush(stdout); immediately after your printf and it would print.

Also you could do this:

fprintf(stderr, "error string");

since stderr is not buffered.

There's also a related question.

Lucas McCoy
+5  A: 

If the segmentation fault occurs too soon after a printf, and the output buffer was not flushed, you won't see the effect of the printf.

pavium
+5  A: 

Most libc implementations buffer printf output. It's usually sufficient to append newline (\n) to the output string to force it to flush the buffers contents.

Falaina
That won't be sufficient. You need to call fflush();
Mitch Wheat
Unless it's redirected to a file, in which case it may be more conventional buffering instead of line buffering.
Paul Tomblin
Ah good points, I assumed line buffering for no good reason, thanks.
Falaina
+3  A: 

You can flush the output buffer right after the printf to to ensure that it will occur before a seg fault. Eg. fflush(stdout)

kb
+3  A: 

Random tip: if you're trying to debug segmentation faults, be sure to try valgrind. It makes it much easier!

Peter
A: 

You've been given a number of answers pointing out buffering of the output stream.

For better or worse, that's nowhere close to the only possibility though. A segmentation fault means the OS has detected that you've done something wrong, typically written outside out allocated memory. For better or worse (mostly worse) doing almost anything in such a situation can change enough of what the program does internally to prevent the problem from being detected, at least at the time/in the situation where it was detected previously.

For example, the segment fault may have been caused by writing through an uninitialized pointer -- that happened to hold a certain value (perhaps some small integer) because a function you'd called previously left that value at the right spot on the stack that when the later function was called, and used that same value as a pointer, it (reasonably dependably) contained a value the OS detected as a place you weren't allowed to write. Putting in a call to printf, however, might mean you're leaving some entirely different value at the spot on the stack that you're using without initialization. You're still writing somewhere you shouldn't, but it might now be somewhere that the OS doesn't know you shouldn't be writing.

Jerry Coffin