我正在开发一个项目,在该项目中我调用了一个触发段错误的函数。我解决了这个问题,但在这个过程中我注意到以下问题。
当我的代码是以下格式时;
main(){
...
std::cout << "Looking for segfault\n"; // this does not print
buggyFunction(); // crashes in here
...
}
buggyFunction(){
...
thing_that_causes_segfault;
...
}
“寻找段错误”行不会打印到 STD,并且程序在 buggyFunction 中崩溃。很好,但是当我在 buggyFunction(); 中添加 cout 行时;
main(){
...
std::cout << "Looking for segfault\n"; // this now *does* print
buggyFunction();
...
}
buggyFunction(){
...
std::cout << "Now we're INSIDE buggy function\n"; // this prints too
thing_that_causes_segfault;
...
}
在 buggy 函数内,两行都会打印(然后崩溃)。
为什么我们会在输出中看到这种差异,具体取决于添加的额外输出调用?它与流的处理有关,还是其他什么?我正在使用 g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3.
这样做的原因是
cout
有一个缓冲区,只有当缓冲区已满时,它才会传递给系统函数并写入控制台。第二次使用 cout
恰好使缓冲区溢出,因此它调用操作系统并清空缓冲区。如果要保证输出已经离开缓冲区,则必须使用std::flush
。您可以使用 std::endl
结束一行并刷新缓冲区。
因为您的行可能不会立即打印出来,因为它已被缓存并且缓存未“刷新”。
std::endl
是换行符 + 刷新,因此强制立即打印输出:
std::cout << "Looking for segfault" << std::endl;
这与缓冲有关。您写入
cout
的内容会附加到仅定期刷新的内部缓冲区中。您可以通过将 std::flush
写入流或将 "\n"
替换为 << std::endl
来显式刷新缓冲区。