当下一条线路上出现公交车故障时,对cout感到好奇

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

本文关键字:cout 好奇 故障 公交车 一条 路上      更新时间:2023-10-16

我很好奇cout是如何处理总线/分段错误的。我在下面粘贴了两个例子。因为我不知道如何复制一个总线错误,你必须从我那里得到这个网格。在本例中,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

默认情况下,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的默认设置是std::cerrstd::clog之间的差异:两个流都写入标准错误流(在UNIXes文件描述符2上),但std::cerr在每次写入后都会刷新其缓冲区,而std::clog则不会。

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

std::coutstd::cerr未被缓冲时被缓冲。如果您使用std::cerr进行测试,无论是否使用std::endl,您都会看到您的消息。

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

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

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

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

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

看看冲洗的效果。