代码如下:
#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的内存,一直调用下去,当数组的地址破坏了返回地址时,就不能再调用递归函数了,这样一来,程序就不能再往下进行了,就出现 段错误 (核心已转储)的错误了,但是如果调用次数较少时,就可以避免这个错误了.
启示:
我们在写递归函数时,一定要注意递归函数的所占内存,如果所占内存较大,就一定得注意递归调用的次数,控制好递归结束条件.