无限循环和无限递归调用之间有什么区别?

时间:2015-01-26 12:01:09

标签: c

以下两个代码之间有什么区别?

int main()
{
    printf("hello\n");
    main();
}

int main()
{
    while(1)
        printf("hello\n");
    return 0;
}

每次第一个被推入堆栈,而第二个堆栈分配只进行一次。在while infinite loop

中是否存在与内存溢出有关的内容

7 个答案:

答案 0 :(得分:4)

如上所述,递归方法将消耗堆栈,最终您将耗尽堆栈空间。

答案 1 :(得分:3)

主要的明显区别是第一个例子肯定会导致堆栈溢出,而第二个例子则没有。

这是因为在第一种情况下,每次调用main()时,返回地址都会在跳转到main()函数的开头之前被推送到堆栈。这些返回地址永远不会从堆栈中弹出,因为函数永远不会返回。

在无限循环中,情况并非如此,只有printf()函数被反复调用并返回,这不会导致堆栈指针发生变化。

答案 2 :(得分:2)

第一个很可能会生成stack overflow,而第二个可能会永远运行。

答案 3 :(得分:1)

你应该注意到C规范实际上没有提到任何关于“堆栈”的内容。使用堆栈只是一个实现细节,编译器设计者/程序员可以自由地使用任何其他方法来实现函数调用和局部变量存储。但是,使用哪种方法,最终会占用一些资源(如内存),就像计算机上的资源一样,其他所有内容都会受到限制,因此使用它们迟早会导致某种溢出情况。

另一方面, empty while循环实际上并不使用任何额外的资源,无论它执行多少次迭代。在你的情况下,它比这更复杂,因为你不知道printf做了什么或它使用了什么资源或printf调用下面的层使用了什么资源,所以也可能存在限制。例如,如果终端窗口设置为使用“无限”回滚,那么该回滚将扩展直到它消耗所有可用内存。

答案 4 :(得分:0)

无限递归会导致丑陋的Segmentation Fault,第二次会永远

答案 5 :(得分:0)

无限递归总是一个可怕的想法。不要那样做。

你受编译器的支配。如果它将它优化为无限循环,那么你很幸运。如果没有,你将耗尽堆栈空间,你的应用程序(很可能)会崩溃。

答案 6 :(得分:0)

循环将永远运行,而递归代码最终会导致堆栈溢出,因为堆栈缓冲区已满。

如果您可以在递归函数和迭代函数之间进行选择,那么您应该更喜欢迭代,因为递归代码可能会导致堆栈溢出和其他问题。此外,它消耗内存(在堆栈上),而循环不会在每次运行时分配更多内存。