Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursive main()-为什么会出现故障?_C_Segmentation Fault_Stack Overflow - Fatal编程技术网

Recursive main()-为什么会出现故障?

Recursive main()-为什么会出现故障?,c,segmentation-fault,stack-overflow,C,Segmentation Fault,Stack Overflow,为什么以下程序出现故障 int main() { main(); } 尽管它是一个没有结束的递归,因此从定义上来说是无效的,但我不明白为什么它会出现故障(gcc 4.4.3和clang 1.5(trunk))。因为它每次调用自己时都会分配一点堆栈空间;最终,它会耗尽堆栈空间并将故障隔离。不过,我有点惊讶它会出现一个segfault;我早就料到了(鼓声) 您会得到一个(!)它会导致堆栈溢出,并在您的系统上被诊断为segfault。它在没有基本情况的情况下递归,从而导致堆栈溢出 int main(

为什么以下程序出现故障

int main() { main(); }

尽管它是一个没有结束的递归,因此从定义上来说是无效的,但我不明白为什么它会出现故障(gcc 4.4.3和clang 1.5(trunk))。

因为它每次调用自己时都会分配一点堆栈空间;最终,它会耗尽堆栈空间并将故障隔离。不过,我有点惊讶它会出现一个segfault;我早就料到了(鼓声)

您会得到一个(!)

它会导致堆栈溢出,并在您的系统上被诊断为segfault。

它在没有基本情况的情况下递归,从而导致堆栈溢出

int main() { main(); }
将导致堆栈溢出

但是,

如下所示的优化版本(非调试模式):

int main() {
   return main();
}

将在尾部递归调用中转换递归,也称为无限循环

每个函数调用都会在堆栈中添加entires,当函数退出时,这些条目将从堆栈中删除。
这里我们有递归函数调用,它没有退出条件。因此,一个接一个的函数调用数量是无限的,这个函数永远不会退出,也永远不会从堆栈中删除实体,这将导致堆栈溢出。

它被称为
堆栈溢出
@wic:据我们所知,它不是一个植物,而是一个真正的问题。非常有趣@T.J:是的,OP是一个天才,甚至连它自己都不知道:)我会担心没有让程序崩溃和烧坏的编译器。应该有一个徽章,可以在不知道答案是堆栈溢出的情况下提问。这台机器有4GB的RAM,它在不到一秒钟的时间内就可以检测出故障。我不认为它的内存用完了。您的意思是堆栈只能很小,以至于发生的速度很快吗?@user2999831堆栈通常限制在1兆字节左右。@user299831:它与您的系统中有多少RAM无关。对于每个线程,都有最大堆栈大小(VisualStudio上为1MB,可以更改)。如果超过该大小,则会出现堆栈溢出。@user299831:stack!=RAM,堆栈空间是在程序开始时预先分配的,并且通常是有限的(我甚至不确定您是否能得到上面提到的1MB sharptooth,但我的C编程在这一点上已经过时了)。此外,今天的机器速度非常快,您的程序除了递归的
main
调用之外什么都不做,它可以非常快地完成,因为它只需要增加(减少?)寄存器并执行跳转。ulimit-s
返回的值以kB为单位,因此8192表示8MB。实际上,对于这个示例,gcc-O3也会优化循环。@尼克,这两个循环有什么不同?@Adil,它依赖于编译器,但如果我们不显式地“返回”主循环,编译器可能不会将其转换为尾部递归。(示例案例:
if(1){main();}返回0;
if(1){return main();}返回0;
)令人惊讶的是,当我第一次单击该链接时,我立即发现堆栈溢出!不是很深的一堆,我想。。。