使用递归的溢出堆栈

Overflowing stack using recursion

本文关键字:溢出 堆栈 递归      更新时间:2023-10-16

使用递归溢出堆栈的方法是什么?我有这样的方法

#include <iostream>
void func()
{
    int arr[100500];
    func();
}
int main()
{
    func();
    std :: cin.ignore(); std :: cin.get();
    return 0;
}

但我不喜欢它。

由于

无限递归,填充堆栈非常容易;

void func() { func(); }

会做得足够好。任何函数调用都会将信息推送到堆栈(至少是返回地址(,因此如果它在某个时候没有停止调用自己,它将耗尽可用的堆栈。

我发现很难理解为什么您会不喜欢您作为示例展示的此类功能。它做需要做的事情,而且做得很快。

但是,优化可能会导致编译器将函数转换为无限循环,因为很容易发现它不执行任何操作。

如果你想要一个实际做某事的函数的演示,

int factorial(int n) { return n<= 0 ? 1 : factorial(n - 1) * n; }

是一个很好的例子,给定一个适当大的 n 值,并且没有编译器优化(或者它可能会发现尾递归的机会并将其转换为循环(。

如果做不到这一点,试试这个(阿克曼函数,一个递归函数的例子,它不是原始递归的,也不会在最后一行进行优化。

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));
} 

读者练习:给定一个智能编译器,可以应用多少优化来最小化递归。

main()中,你调用func()然后调用func()(本身(,然后调用func()(本身(等。

每次调用函数时,指针都会被推送到堆栈上。堆栈是有限的内存量,最终会填满,然后你会得到一个stack overflow

由于您的程序将无休止地调用func()堆栈将很快填满。

另请注意,局部变量arr也将在堆栈上分配。这将更快地填满堆栈。

当递归太深时,可能会导致堆栈溢出,因为函数局部变量和返回地址存储在堆栈上。在您的情况下,您有无限递归,也就是说,您没有条件阻止 func(( 调用自身,因此您将溢出堆栈。

没有定义的限制,这取决于运行递归的语言和体系结构。