递归C++函数中的堆栈溢出错误
Stack Overflow error in recursive C++ function
#include<iostream>
using namespace std;
int f()
{
static int count=0;
count++;
if (count>=5000)
return count;
return f();
}
int main ()
{
cout<<f();
return 0;
}
计数值超过 4800 后,此函数会使堆栈溢出,任何人都可以告诉如何解决此问题吗?
不要使用递归 - 使用常规循环。每次调用 f()
方法时,都会占用堆栈上的几个单词,并且会在某个时候溢出它。
通常,有办法增加堆栈大小(取决于您的系统和/或编译器),但我不想推荐这样做(特别是因为它会再次溢出,只是当 count 的值大于 4800 时)。
或者只是int f(){ return 5000; }
就可以了。
假设你想递归运行,你可以关闭调试模式,那么你就会成功(因为Visual Studio在堆栈上添加了额外的东西来检测你是否"破坏"堆栈[这就是它如何说"变量周围的堆栈x
被覆盖"或任何确切的消息)。
然而,依靠能够递归地进行大量调用通常是一个糟糕的计划——在某些时候,它仍然会失败。无论是 5000、50000 还是 500000,都只是"这个函数需要多少堆栈空间"的问题。我想说的是,任何没有大约 100 级递归的自然限制的东西都是"你以错误的方式解决问题"的情况。如果你确实有这么大的递归级别,最好使用软件堆栈(例如 std::stack
在 C++) 中),并将 crrent 状态保存在该堆栈上,并使用函数中的软件将其恢复。
堆栈空间不足是最糟糕的运行时问题之一,因为您实际上无能为力 - 您可能可以执行某些操作来打印错误消息或类似操作,但实际上没有办法"给进程更多的堆栈空间并继续"。当进程内存不足或类似内容时,您可以说"好吧,我不会分配它,并给用户一个很好的错误消息,说'我不能这样做',然后很好地保存当前状态并退出,例如。
[是的,你可以增加应用程序的堆栈大小,但这实际上应该只作为真正的最后手段来完成,并且只有当你完全理解为什么你需要这么大的堆栈时 - 如果你需要一个更大的堆栈,这通常是你做错了什么]。
我假设这是为了学习递归的学术练习。 (如果不是,请不要为此使用递归!
编写函数的更好方法:
#include <iostream>
int f(int i)
{
if (i >= 5000)
{
return i;
}
else
{
return f(i + 1);
}
}
int f_alt1()
{
return 5000;
}
int f_alt2()
{
int i = 0;
for (; i <= 5000; ++i);
return i;
}
int main()
{
std::cout << f(0) << std::endl;
return 0;
}
这仍然会消耗比返回常量或在循环中递增更多的运行时资源,并且如果将所需的常量增加到一个明显更大的数字,则需要增加堆栈大小。
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- C++ 对象数组堆栈溢出
- 有没有一种方法可以捕获进程中的堆栈溢出?C++Linux
- 对象接收堆栈溢出异常 c++ 的排序向量
- 将公共递归转换为尾递归,因为大型输入的堆栈溢出
- C++ 中递归期间的堆栈溢出
- 启动 dll 时 C# 环境堆栈溢出
- 在C++中使用数组时如何防止堆栈溢出?
- 如何修复递归函数导致的堆栈溢出错误?C++
- 当我尝试为结构分配新指针时出现堆栈溢出错误
- 为什么析构函数无休止地调用自己(导致堆栈溢出)?
- 为什么堆栈溢出?如有建议,不胜感激
- 主函数执行时C++堆栈溢出异常
- 如何在不导致堆栈溢出的情况下计算非常大的数字和很小的 HCF.我正在使用欧几里得算法
- 我正在尝试使用回溯来解决 N queen 问题,但在编译时它会给出运行时错误(动态堆栈缓冲区溢出)
- 如何在Windows上报告堆栈缓冲区溢出
- 如何抑制来自 gcc 中地址清理器的堆栈缓冲区溢出
- 声明大数组时堆栈/堆溢出
- c++中栈溢出和分段错误的危险