Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Curious about cout when there is a bus error on some next line

I am curious about how cout work with bus/segmentation errors. I have two examples pasted below. Because I don't know how to replicate a bus error you have to take if from me that grid.DoMovement, in this example, throws a bus error. While I was cout-ing something before the bus error line I noticed that if I put an endline in it will print it out fine, but if I don't put an endl in it does not. The examples at the bottom show what I mean.
Why is it that if you don't put an endline in the cout and you have a bus error on one of the later lines that it doesn't print out the "example 2"?

Example 1:

std::cout << "example 1" << endl;
grid.DoMovement(); 

Output is

works
bus error

Example 2:

std::out << "example 2";
grid.DoMovement(); 

Output is

bus error
like image 567
Niek de Klein Avatar asked Nov 23 '25 02:11

Niek de Klein


1 Answers

By default IOStreams are buffered. Anything only written to the buffer won't be displayed. When you use std::endl with a stream a newline gets added and the stream is flushed. Note, that normally you don't want to have the stream flushed: Frequent flushing of flie streams can reduce performance dramatically! Thus, it is a good idea not to use std::endl but '\n' if you want a newline. If you really want to flush a stream you can explicitly use std::flush which just flushes the stream.

During debugging it may be helpful to have all output appear as soon as it is written so that a crash doesn't prevent output from showing. If you follow the above advise and don't flush frequently a lot of output may get buffered. The simple remedy for this is to use std::unitbuf: this manipulator turns on the flag std::ios_base::unitbuf cause the output streams to be flushed after each insertion. You can turn the flag off again using std::nounitbuf to avoid slowdown in code sections which are known to work (or, at least, known not to fail in a too dramatic way):

std::cout << std::unitbuf;   // turn on automatic flushing
problematic_code();
std::cout << std::nounitbuf; // turn off automatic flushing

The default settings for the std::ios_base::unitbuf is the differences between std::cerr and std::clog: both stream write to the standard error stream (on UNIXes file descriptor 2) but std::cerr flushes its buffer after each write while std::clog does not.

like image 65
Dietmar Kühl Avatar answered Nov 25 '25 17:11

Dietmar Kühl