2

我很好奇 cout 如何处理总线/分段错误。我在下面粘贴了两个示例。因为我不知道如何复制您必须采取的总线错误,如果从我这里 grid.DoMovement,在这个例子中,抛出一个总线错误。当我在总线错误行之前计算某些内容时,我注意到如果我在其中放置一个 endline,它会很好地打印出来,但如果我不放一个 endl,它就不会。底部的例子说明了我的意思。
为什么如果你没有在 cout 中放置一个结束行并且你在后面的一行中有一个总线错误,它不会打印出“示例 2”?

示例 1:

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

输出是

works
bus error

示例 2:

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

输出是

bus error
4

4 回答 4

4

std::endl不仅向流中添加新行,还刷新输出流的当前缓冲区。如果在输出流缓冲区中有一些数据时出现总线错误,您将看不到数据。

于 2012-10-11T18:07:36.773 回答
4

默认情况下 IOStreams 被缓冲。仅写入缓冲区的任何内容都不会显示。当您使用std::endl流时,会添加换行符并刷新流。请注意,通常您希望刷新流:频繁刷新飞行流会显着降低性能!std::endl因此,'\n'如果您想要换行符,最好不要使用。如果你真的想刷新一个流,你可以显式地使用std::flush它来刷新流。

在调试期间,让所有输出在写入后立即显示可能会有所帮助,这样崩溃不会阻止输出显示。如果您遵循上述建议并且不经常刷新,很多输出可能会被缓冲。对此的简单补救措施是使用std::unitbuf:此操纵器打开标志std::ios_base::unitbuf导致每次插入后刷新输出流。您可以再次关闭该标志,std::nounitbuf以避免在已知可以工作的代码部分中减慢速度(或者,至少,已知不会以过于戏剧性的方式失败):

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

的默认设置是和std::ios_base::unitbuf之间的区别:两者都流写入标准错误流(在 UNIX 文件描述符 2 上),但在每次写入后刷新其缓冲区,而没有。std::cerrstd::clogstd::cerrstd::clog

于 2012-10-11T18:47:08.937 回答
1

std::cout不是时被缓冲std::cerr。如果您使用std::cerr、 或不使用进行测试std::endl,您将看到您的消息。

http://www.cplusplus.com/reference/iostream/manipulators/endl

于 2012-10-11T18:07:33.437 回答
1

endl是一个“神奇”的操纵器,它输出换行符并刷新输出缓冲区。

程序结束时缓冲区通常也会被刷新,因此您通常看不到endl. 但是,如果您的程序此后不久崩溃,则不会刷新缓冲区,并且不会出现输出。

您可以将第二个示例更改为

std::out << "example 2" << flush;

看看冲洗的效果。

于 2012-10-11T18:08:11.080 回答