程序递归深度问题---爆栈的产生与解决
一、产生
在函数调用过程中,反复调用自己的函数称为递归函数。
如下面程序的函数调用过程为
(1) main里调用Hello
(2) Hello输出”Hello”后继续调用Hello函数
(3)一直这样继续
会发生什么?
没完没了一直到“爆栈”,也就是栈溢出,也即stackoverflow。
在windows的DEV-cpp编译下你会看到
我们程序返回0代表程序正常结束,这个返回值代表程序已经爆栈
复制#include<bits/stdc++.h>
using namespace std;
void Hello()
{
cout<<"Hello"<<endl;
Hello();
}
int main()
{
Hello();
return 0;
}
我们可以记录下递归的次数
复制#include<bits/stdc++.h>
using namespace std;
void Hello(int tot)
{
cout<<"Hello"<<" "<<tot<<endl;
Hello(tot+1);
}
int main()
{
Hello(0);
return 0;
}
我们也可以使用全局变量记录下递归的次数
为什么两个值都锁定在了64890呢,多传递几个参数呢,你会发现依旧到了这个神奇的数字,所以递归深度与传递的参数个数是无关的。
那这个64890究竟代表着什么呢,我们再来一个程序玩一下。
复制#include<bits/stdc++.h>
using namespace std;
int tot;
void test()
{
int buffer[1024];
tot++;
cout<<tot<<"\n";
test();
}
int main()
{
test();
}
这个程序能运行503次,假设每次递归调用的内存开销为x,那么这段程序的栈开销为,一个int为4B,x为每次递归的开销
他和是相等的,,我们可以解出x的值为32,即每次递归开销为32B,栈内存开销为207360B,为2MB。
局部变量也是使用栈内存的,我们可以验证一下,你可以在主函数内开辟的数组,就正好超过了这个大小。查阅相关资料你也会知道window下编译出的程序的栈缺省值(默认值)为2MB。
我们知道黑白图像那个题必须要广搜才能过,因为栈空间超过了大小,那么我把这个数据缩小到哪个数依旧可以过呢
假设这个图的大小为N*N,我们每次递归需要32B的开销,如果全是1,那么需要递归次,我们可以求得N为256。256试一下发现不行,因为我们程序本身也需要一点点栈内存,要不然我们Hello连续递归运行次数应该为65536,但是确没有达到,当然255就可以了。
复制#include <bits/stdc++.h>
using namespace std;
#define N 255
int n=N;
char s[1023][10223];
char vis[N][N];
int dir[4][2]={1,0,0,1,-1,0,0,-1};
int tx,ty,i;
void dfs(int x,int y)
{
for(i=0;i<4;i++)
{
tx=x+dir[i][0];
ty=y+dir[i][1];
if(tx<0||tx>=n||ty<0||ty>=n||vis[tx][ty])continue;
vis[tx][ty]=1;
dfs(tx,ty);
}
}
int main()
{
dfs(0,0);
return 0;
}
二、解决
如何解决呢,使用递归前一定要估计下递归的深度,深度在6e4以上请直接放弃递归,请使用非递归的形式实现。当然你也可以手动扩栈(🐶
当然问题的本质是操作系统和编译器的内存管理让我们程序崩了
本文来自博客园,作者:暴力都不会的蒟蒻,转载请注明原文链接:https://www.cnblogs.com/BobHuang/p/14532924.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2018-03-14 GitHub上传文件夹及Git命令