使用递归溢出堆栈

时间:2012-02-09 07:43:27

标签: c++

使用递归溢出堆栈的方法有哪些? 我有这样的方式

#include <iostream>

void func()
{
    int arr[100500];
    func();
}

int main()
{
    func();

    std :: cin.ignore(); std :: cin.get();

    return 0;
}

但我不喜欢它。

3 个答案:

答案 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()调用它自己,因此你溢出了堆栈。

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

相关问题