Stack Overflow

  最近在写扫雷程序,扫雷里边有一个功能是你在扫雷的时候如果周围没有雷,你就会向周围开始扩展

 

就像这张图右边这样 直到你的空格被你的数字所包围了,换算到代码中来之后,就会是一个循环或者是一个递归程序

void  Extend(char arr[ROWS][COLS], char arr1[ROWS][COLS], int x, int y)

{

if ((x<1) || (y<1) || (x>9) || (y>9))

return;

if (arr[x - 1][y] == '0')

{

if (arr1[x - 1][y] != ' ')

arr1[x - 1][y] = ' ';

Extend(arr, arr1, x - 1, y);

}

if (arr[x + 1][y] == '0')

{

if (arr1[x + 1][y] != ' ')

arr1[x + 1][y] = ' ';

Extend(arr, arr1, x + 1, y);

}

if (arr[x][y + 1] == '0')

{

if (arr1[x][y + 1] != ' ')

arr1[x][y + 1] = ' ';

Extend(arr, arr1, x, y+1);

}

if (arr[x - 1][y + 1] == '0')

{

if (arr1[x - 1][y + 1] != ' ')

arr1[x - 1][y + 1] = ' ';

Extend(arr, arr1, x-1, y+1);

}

if (arr[x + 1][y + 1] == '0')

{

if (arr1[x + 1][y + 1] != ' ')

arr1[x + 1][y + 1] = ' ';

Extend(arr, arr1, x+1, y+1);

}

if (arr[x][y - 1] == '0')

{

if (arr1[x][y - 1] != ' ')

arr1[x][y - 1] = ' ';

Extend(arr, arr1, x, y-1);

}

if (arr[x + 1][y - 1] == '0')

{

if (arr1[x + 1][y-1] != ' ')

arr1[x + 1][y - 1] = ' ';

Extend(arr, arr1, x+1, y-1);

}

if (arr[x - 1][y - 1] == '0')

{

if (arr1[x - 1][y+1] != ' ')

arr1[x - 1][y + 1] = ' ';

Extend(arr, arr1, x-1, y-1);

}

}

这是我写的扩展的代码(现在已经改了很多遍了,已经不是这样了),之后这个代码我仔细检查了很多遍,思维逻辑不断的完整,但是我的程序依然不可以运行。

 

Stack Overflow,不断的在提示,我最初一直搞不懂为什么会出现这个问题,我一直以为是我的函数访问越界了出现了问题,但是仔仔细细想了很多遍之后发现并不是这个问题。

因为栈一般默认为1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。

因为我的代码中不断的调用获取雷数目的函数,以及不断的调用扩展函数本身所以他的内存栈不够用了,导致出现了这个问题。所以大家如果以后出现这个问题,在仔细阅读自己代码发现没问题的时候,就要去想解决这个栈溢出的情况。

解决方案:

方法一:用栈把递归转换成非递归

通常,一个函数在调用另一个函数之前,要作如下的事情:a)将实在参数,返回地址等信息传递给被调用函数保存; b)为被调用函数的局部变量分配存储区;c)将控制转移到被调函数的入口. 从被调用函数返回调用函数之前,也要做三件事情:a)保存被调函数的计算结果;b)释放被调函数的数据区;c)依照被调函数保存的返回地址将控制转移到调用函数.所有的这些,不论是变量还是地址,本质上来说都是"数据",都是保存在系统所分配的栈中的. 那么自己就可以写一个栈来存储必要的数据,以减少系统负担。

方法二:增加你栈的大小

 



这里我将我的栈保留大小扩大到了很大,听说舍友不知道加了几个0之后发现360加速球都变红了..但是我们的问题依然没有解决,可能是我们的代码调用次数实在是过多.....希望这个方法二可以解决大家某些人的问题。

  等我写出来我的扫雷拓展之后再出现在博客里吧。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值