2011-07-27 112 views
2

我正在致力于一个项目,我调用一个触发段错误的函数。我解决了这个问题,但是在这个过程中我注意到了以下几点G ++编译器:Segfault处理

当我的代码是格式;

main(){ 
    ... 
    std::cout << "Looking for segfault\n"; // this does not print 
    buggyFunction(); // crashes in here 
    ... 
} 

buggyFunction(){ 
    ... 
    thing_that_causes_segfault; 
    ... 
} 

线“寻找段错误”不打印到性病,并在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; 
    ... 
} 

在越野车功能,两行打印(然后它崩溃)。

为什么我们在输出中看到这种差异,取决于额外的输出呼叫的增加?它与流处理有关还是其他?我正在使用g ++(Ubuntu 4.4.3-4ubuntu5)4.4.3。

回答

7

原因是cout有一个缓冲区,它只会传递给系统函数并在缓冲区满时写入控制台。你的第二次使用cout恰好溢出缓冲区,所以它调用操作系统并清空缓冲区。如果要确保输出已离开缓冲区,则必须使用std::flush。您可以结束一行并使用std::endl刷新缓冲区。

+2

或者,您可以用'的std :: cerr',这是无缓冲(大概为错误报告的目的)。 –

+1

即使使用“std :: endl”而不是“\ n”,仍然不能保证该行将被打印,但是使用'std :: endl'打印行的几率更好。两个原因为什么这仍然可能无效:(1)可能还有其他缓冲正在进行,(2)SEGFAULT是对某种未定义行为的回应。对于未定义的行为没有保证。 –

+0

D'OH!我以前有一个endl(专门用来刷新流),但是在调试的某个时候它已经被删除了,我忘了重新放入 - 我很少使用\ n。 – Alex

2

它与缓冲有关。你写给cout的东西被附加到一个内部缓冲区,只有周期性的刷新。您可以通过将std::flush写入流,或将"\n"替换为<< std::endl来明确刷新缓冲区。

3

因为您的行可能无法立即打印出来,因为它被缓存且缓存未被“刷新”。 std::endl是一个换行符+冲洗从而部队立即打印输出:

std::cout << "Looking for segfault" << std::endl;