什么是递归
调用函数的时候,比如 main 函数调用 add 时候,需要为 add 分配内存,我们管这个这个叫 Frame,如果 add 函数自己调用自己叫做递归,它调用的时候它会分配新的栈桢么?就是说自己调用自己的时候栈帧的状态是什么样子的?
所谓的自己调用自己实质是什么,只不过执行了相同的代码,但是它依然会分配新的栈帧,一直往上面分配,只不过栈帧的内存状态未必是一样的,数据可能会不一样。.text
中使用的代码一样的而已。如果这个递归函数不小心写错了没有中止,那么会一直往上分配,直到整个栈的空间耗光,耗光的时候会引发一种叫堆栈溢出。
Go 与 C 栈大小差异
每种语言甚至是每种操作系统甚至不同平台栈空间大小未必是一样的,有些可能是1MB,有些可能是10MB,Go语言是1GB,另外还有些语言对它是有限制的,它不是限制栈内存耗光了,而是调用递归深度如果超出多少就会认为你是溢出了。比如Python语言限制1000次。
为什么会引起堆栈溢出(stack overflow)
堆栈溢出多处情况下发生在递归调用,因为递归调用写的算法有问题,可能没有明确的终止,这时候可能会形成溢出。
堆栈溢出有这样一个问题,我们写个算法遍历一个非常大的xml文件使用递归,比如以深度优先模式扫描,肯定使用递归调用不停的一级一级的扫描,扫描完一点一点的返回,当不知道深度有多大的时候我们怎么样避免堆栈溢出呢?
比如一个树,深度控制在三层,那么可能广度很多,深度优先之后接下来广度,这样做法堆栈依然会爆掉,使用计数器不好控制,比如计数器超过