死递归:“段错误”产生的可能原因之一
我和Linux下的“段错误”的第一次邂逅是在前几天,当我尝试着去写一个控制台下的扫雷程序的时候。
扫雷程序在这里且不谈算法的优劣,个人认为关键的两点一个是给雷点周围的点置上相应的雷数,另一点就是当点一个非雷点时自己开连着的那一版非雷区。
这里的第二点我使用的是递归算法。到目前为止,虽然我的简单版程序已经基本完成,可我还没来得及找到别人的源程序来学习,至少在我的想象力范围内好像是必须得使用递归才行。
在初次写好测试时,有几次是开一个点就提示“段错误”,有几次是开了几个非雷点也非空白点后再开某点提示“段错误”。在google上搜了下,网友们一般认为造成“段错误”的原因是:访问了不存在的内存,或者系统保留的内存地址,比如0地址。但是我感觉这放在我的程序里并不适用,因为感觉在我的程序里没有这样的语句。用gdb调试未果--提示了错误信息,但我一头雾水。所以只好添加了一小段代码,让程序在我开始扫雷前先将雷点信息全部输出来,然后对照这些雷点信息尝试测试了多次后,终于发现原来是写了个死递归。众所周知,递归运算每次都会对现场信息进行保留以备下次调用时使用,而这些信息就是保存在堆栈段里,我想这里系统提示的“段错误”应该是指堆栈段溢出的问题。
果然不出我所料,更正了无限递归的问题后一切正常了,成功实现了想要的目标。
产生错误的代码原理如下:
当我开一个空白点(即它又不是雷而且周围雷数字为0)那就要对它周围的几个点进行递归检查以便自动打开一片,倘若不判断它周围的某点以前是不是已经检查过了,那程序将有可能在两个点之间反复递归检查对方,如此一来,死递归便形成了。
扫雷程序在这里且不谈算法的优劣,个人认为关键的两点一个是给雷点周围的点置上相应的雷数,另一点就是当点一个非雷点时自己开连着的那一版非雷区。
这里的第二点我使用的是递归算法。到目前为止,虽然我的简单版程序已经基本完成,可我还没来得及找到别人的源程序来学习,至少在我的想象力范围内好像是必须得使用递归才行。
在初次写好测试时,有几次是开一个点就提示“段错误”,有几次是开了几个非雷点也非空白点后再开某点提示“段错误”。在google上搜了下,网友们一般认为造成“段错误”的原因是:访问了不存在的内存,或者系统保留的内存地址,比如0地址。但是我感觉这放在我的程序里并不适用,因为感觉在我的程序里没有这样的语句。用gdb调试未果--提示了错误信息,但我一头雾水。所以只好添加了一小段代码,让程序在我开始扫雷前先将雷点信息全部输出来,然后对照这些雷点信息尝试测试了多次后,终于发现原来是写了个死递归。众所周知,递归运算每次都会对现场信息进行保留以备下次调用时使用,而这些信息就是保存在堆栈段里,我想这里系统提示的“段错误”应该是指堆栈段溢出的问题。
果然不出我所料,更正了无限递归的问题后一切正常了,成功实现了想要的目标。
产生错误的代码原理如下:
当我开一个空白点(即它又不是雷而且周围雷数字为0)那就要对它周围的几个点进行递归检查以便自动打开一片,倘若不判断它周围的某点以前是不是已经检查过了,那程序将有可能在两个点之间反复递归检查对方,如此一来,死递归便形成了。
更多原创技术内容,可以通过公众号「闷骚的程序员」订阅:
![闷骚的程序员](https://cdn.jsdelivr.net/gh/mzlogin/mzlogin.github.io@master/assets/images/qrcode.jpg)
![闷骚的程序员](https://cdn.jsdelivr.net/gh/mzlogin/mzlogin.github.io@master/assets/images/qrcode.jpg)