使用递归溢出堆栈的方法有哪些? 我有这样的方式
#include <iostream>
void func()
{
int arr[100500];
func();
}
int main()
{
func();
std :: cin.ignore(); std :: cin.get();
return 0;
}
但我不喜欢它。
答案 0 :(得分:2)
由于无限递归,填充堆栈非常容易;
void func() { func(); }
会做得很好。任何函数调用都会将信息压入堆栈(至少是一个返回地址),因此如果它在某个时刻没有停止调用自身,它将会耗尽可用的堆栈。
我发现很难理解为什么你不喜欢这样的功能,就像你已经展示过这样做的一个例子。它可以满足需要,并且可以快速完成。
但是,优化可能会导致编译器将函数转换为无限循环,因为很容易发现它没有做任何事情。
如果您想要演示实际执行某项操作的功能,
int factorial(int n) { return n<= 0 ? 1 : factorial(n - 1) * n; }
是一个很好的例子,给定一个适当大的n值,并且没有编译器优化(或者它可能发现尾递归的机会并将其转换为循环)。
如果做不到这一点,试试这个(Ackermann的函数,一个递归函数的例子,它不是原始递归的,也不会在最后一行进行优化。
unsigned int A(unsigned int m, unsigned int n)
{
if (m == 0) return n + 1;
if (n == 0) return A(m - 1, 1);
return A(m - 1, A(m, n - 1));
}
为读者练习:给定一个智能编译器,可以应用多少优化来最小化递归。
答案 1 :(得分:0)
在main()
中,您拨打func()
,然后调用func()
(本身),然后调用func()
(本身)等。
每次调用函数时,指针都会被压入堆栈。堆栈是有限的内存,最终将填充,然后您将获得stack overflow
。
由于您的程序将无休止地调用func()
,因此堆栈将很快填满。
另请注意,局部变量arr
也将在堆栈上分配。这将更快地填满堆栈。
答案 2 :(得分:0)
当递归过深时,由于函数局部变量和返回地址存储在堆栈中,因此可能导致堆栈溢出。在你的情况下,你有无限的递归,也就是说,你没有条件来阻止func()调用它自己,因此你溢出了堆栈。
没有定义的限制,它取决于您运行递归的语言和体系结构。