正在讨论的程序尝试计算sum-of-first-n-natural-numbers
using recursion
。我知道这可以使用一个简单的公式来完成n*(n+1)/2
但这里的想法是使用recursion
.
程序如下:
#include <stdio.h>
unsigned long int add(unsigned long int n)
{
return (n == 0) ? 0 : n + add(n-1);
}
int main()
{
printf("result : %lu \n", add(1000000));
return 0;
}
该计划效果很好n = 100,000
但当值n
增加到1,000,000
它导致了Segmentation fault (core dumped)
以下内容摘自gdb
信息。
Program received signal SIGSEGV, Segmentation fault.
0x00000000004004cc in add (n=Cannot access memory at address 0x7fffff7feff8
) at k.c:4
我的问题:
是否有任何硬连线限制recursion depth
in C
?或者是recursion depth
取决于可用的堆栈内存?
程序收到 reSIGSEGV 信号的可能原因有哪些?
一般来说,限制是堆栈的大小。每次调用函数时,都会消耗一定量的堆栈(通常取决于函数)。吃掉的量就是栈帧,函数返回时就回收了。当程序启动时,堆栈大小几乎是固定的,要么由操作系统指定(并且通常可以在那里调整),要么甚至在程序中硬编码。
某些实现可能具有一种可以在运行时分配新堆栈段的技术。但总的来说,他们没有。
某些函数将以稍微难以预测的方式消耗堆栈,例如当它们在那里分配可变长度数组时。
某些函数可能会被编译为使用尾部调用,从而保留堆栈空间。有时您可以重写您的函数,以便所有调用(例如对其本身)作为它执行的最后一件事发生,并期望您的编译器对其进行优化。
要准确了解每次调用函数需要多少堆栈空间并不容易,并且会受到编译器的优化级别的影响。在您的情况下,一种便宜的方法是打印&n
每次被调用时;n
很可能位于堆栈上(特别是因为程序需要获取其地址 - 否则它可能位于寄存器中),并且它的连续位置之间的距离将指示堆栈帧的大小。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)