递归调用的栈溢出

代码如下:

#include <stdio.h>
#include <stdlib.h>

int recurse(int x) {
    int a[1<<15];  /* 4 * 2^15 =  128 KiB */
    printf("x = %d.  a at %p\n", x, a); 
    a[0] = (1<<14)-1;
    a[a[0]] = x-1;
    if (a[a[0]] == 0)
	return -1;
    return recurse(a[a[0]]) - 1;
}
int main(int argc, char *argv[]) {
    int x = 100;
    if (argc > 1)
	x = atoi(argv[1]);
    int v = recurse(x);
    printf("x = %d.  recurse(x) = %d\n", x, v);
    return 0;
}
22

运行结果如下:

hxl@hxl-virtual-machine:~/桌面/task/code$ ./r 100
x = 100.  a at 0x7ffcfce0afd0
x = 99.  a at 0x7ffcfcdeafa0
x = 98.  a at 0x7ffcfcdcaf70
x = 97.  a at 0x7ffcfcdaaf40
x = 96.  a at 0x7ffcfcd8af10
x = 95.  a at 0x7ffcfcd6aee0
x = 94.  a at 0x7ffcfcd4aeb0
x = 93.  a at 0x7ffcfcd2ae80
x = 92.  a at 0x7ffcfcd0ae50
x = 91.  a at 0x7ffcfcceae20
x = 90.  a at 0x7ffcfcccadf0
x = 89.  a at 0x7ffcfccaadc0
x = 88.  a at 0x7ffcfcc8ad90
x = 87.  a at 0x7ffcfcc6ad60
x = 86.  a at 0x7ffcfcc4ad30
x = 85.  a at 0x7ffcfcc2ad00
x = 84.  a at 0x7ffcfcc0acd0
x = 83.  a at 0x7ffcfcbeaca0
x = 82.  a at 0x7ffcfcbcac70
x = 81.  a at 0x7ffcfcbaac40
x = 80.  a at 0x7ffcfcb8ac10
x = 79.  a at 0x7ffcfcb6abe0
x = 78.  a at 0x7ffcfcb4abb0
x = 77.  a at 0x7ffcfcb2ab80
x = 76.  a at 0x7ffcfcb0ab50
x = 75.  a at 0x7ffcfcaeab20
x = 74.  a at 0x7ffcfcacaaf0
x = 73.  a at 0x7ffcfcaaaac0
x = 72.  a at 0x7ffcfca8aa90
x = 71.  a at 0x7ffcfca6aa60
x = 70.  a at 0x7ffcfca4aa30
x = 69.  a at 0x7ffcfca2aa00
x = 68.  a at 0x7ffcfca0a9d0
x = 67.  a at 0x7ffcfc9ea9a0
x = 66.  a at 0x7ffcfc9ca970
x = 65.  a at 0x7ffcfc9aa940
x = 64.  a at 0x7ffcfc98a910
x = 63.  a at 0x7ffcfc96a8e0
x = 62.  a at 0x7ffcfc94a8b0
x = 61.  a at 0x7ffcfc92a880
x = 60.  a at 0x7ffcfc90a850
x = 59.  a at 0x7ffcfc8ea820
x = 58.  a at 0x7ffcfc8ca7f0
x = 57.  a at 0x7ffcfc8aa7c0
x = 56.  a at 0x7ffcfc88a790
x = 55.  a at 0x7ffcfc86a760
x = 54.  a at 0x7ffcfc84a730
x = 53.  a at 0x7ffcfc82a700
x = 52.  a at 0x7ffcfc80a6d0
x = 51.  a at 0x7ffcfc7ea6a0
x = 50.  a at 0x7ffcfc7ca670
x = 49.  a at 0x7ffcfc7aa640
x = 48.  a at 0x7ffcfc78a610
x = 47.  a at 0x7ffcfc76a5e0
x = 46.  a at 0x7ffcfc74a5b0
x = 45.  a at 0x7ffcfc72a580
x = 44.  a at 0x7ffcfc70a550
x = 43.  a at 0x7ffcfc6ea520
x = 42.  a at 0x7ffcfc6ca4f0
x = 41.  a at 0x7ffcfc6aa4c0
x = 40.  a at 0x7ffcfc68a490
x = 39.  a at 0x7ffcfc66a460
x = 38.  a at 0x7ffcfc64a430
段错误 (核心已转储)
hxl@hxl-virtual-machine:~/桌面/task/code$ ./r 20
x = 20.  a at 0x7ffe345245a0
x = 19.  a at 0x7ffe34504570
x = 18.  a at 0x7ffe344e4540
x = 17.  a at 0x7ffe344c4510
x = 16.  a at 0x7ffe344a44e0
x = 15.  a at 0x7ffe344844b0
x = 14.  a at 0x7ffe34464480
x = 13.  a at 0x7ffe34444450
x = 12.  a at 0x7ffe34424420
x = 11.  a at 0x7ffe344043f0
x = 10.  a at 0x7ffe343e43c0
x = 9.  a at 0x7ffe343c4390
x = 8.  a at 0x7ffe343a4360
x = 7.  a at 0x7ffe34384330
x = 6.  a at 0x7ffe34364300
x = 5.  a at 0x7ffe343442d0
x = 4.  a at 0x7ffe343242a0
x = 3.  a at 0x7ffe34304270
x = 2.  a at 0x7ffe342e4240
x = 1.  a at 0x7ffe342c4210
x = 20.  recurse(x) = -20

代码分析`:
这段代码首先定义了一个函数,这个函数是用来实现递归的,函数里定义了一个2的15次方个元素大小的int型数组,然后输出数组的地址,然后就进行递归调用,一直到x=0才结束,但是运行结果中却出现了 段错误 (核心已转储),这是为什么呢,因为递归调用是一个非常占用内存的操作,调用函数的过程中会将返回地址入栈,用来找到自己回去的路,而递归调用一直是调用进行中,一直等到递归结束才一层层返回,但是遗憾的是,由于递归函数中的定义的这个数组太大了,要占用128kb内存,意味着每调用一次就会占用大于128kb的内存,一直调用下去,当数组的地址破坏了返回地址时,就不能再调用递归函数了,这样一来,程序就不能再往下进行了,就出现 段错误 (核心已转储)的错误了,但是如果调用次数较少时,就可以避免这个错误了.
启示:
我们在写递归函数时,一定要注意递归函数的所占内存,如果所占内存较大,就一定得注意递归调用的次数,控制好递归结束条件.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值