runaway.c代码解释

    xiaoxiao2025-02-16  17

    代码功能

    程序可以看出定义非常大的数组时局部变量占用空间太大,已经不能在分配空间给栈,导致溢出。

    栈溢出

    栈存放局部变量,参数,返回值和返回地址。

    int recurse(int x) { int a[1<<15]; /* 4 * 2^15 = 64 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;//递归调用 }

    递归函数调用的是自己本身,无论是递归还是非递归每调用一次函数就会生成一个新的栈帧,当函数调用完之后,栈帧被销毁,保留返回值和返回地址。栈溢出可能是因为递归次数太多,也可能因为局部变量占用空间太大。

    代码块

    #include <stdio.h> #include <stdlib.h> int recurse(int x) { int a[1<<15]; /* 4 * 2^15 = 64 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; }

    测试结果

    x = 100的结果

    x = 100. a at 0x7ffdfaf8cd10 x = 99. a at 0x7ffdfaf6cce0 x = 98. a at 0x7ffdfaf4ccb0 x = 97. a at 0x7ffdfaf2cc80 x = 96. a at 0x7ffdfaf0cc50 x = 95. a at 0x7ffdfaeecc20 x = 94. a at 0x7ffdfaeccbf0 x = 93. a at 0x7ffdfaeacbc0 x = 92. a at 0x7ffdfae8cb90 x = 91. a at 0x7ffdfae6cb60 x = 90. a at 0x7ffdfae4cb30 x = 89. a at 0x7ffdfae2cb00 x = 88. a at 0x7ffdfae0cad0 x = 87. a at 0x7ffdfadecaa0 x = 86. a at 0x7ffdfadcca70 x = 85. a at 0x7ffdfadaca40 x = 84. a at 0x7ffdfad8ca10 x = 83. a at 0x7ffdfad6c9e0 x = 82. a at 0x7ffdfad4c9b0 x = 81. a at 0x7ffdfad2c980 x = 80. a at 0x7ffdfad0c950 x = 79. a at 0x7ffdfacec920 x = 78. a at 0x7ffdfaccc8f0 x = 77. a at 0x7ffdfacac8c0 x = 76. a at 0x7ffdfac8c890 x = 75. a at 0x7ffdfac6c860 x = 74. a at 0x7ffdfac4c830 x = 73. a at 0x7ffdfac2c800 x = 72. a at 0x7ffdfac0c7d0 x = 71. a at 0x7ffdfabec7a0 x = 70. a at 0x7ffdfabcc770 x = 69. a at 0x7ffdfabac740 x = 68. a at 0x7ffdfab8c710 x = 67. a at 0x7ffdfab6c6e0 x = 66. a at 0x7ffdfab4c6b0 x = 65. a at 0x7ffdfab2c680 x = 64. a at 0x7ffdfab0c650 x = 63. a at 0x7ffdfaaec620 x = 62. a at 0x7ffdfaacc5f0 x = 61. a at 0x7ffdfaaac5c0 x = 60. a at 0x7ffdfaa8c590 x = 59. a at 0x7ffdfaa6c560 x = 58. a at 0x7ffdfaa4c530 x = 57. a at 0x7ffdfaa2c500 x = 56. a at 0x7ffdfaa0c4d0 x = 55. a at 0x7ffdfa9ec4a0 x = 54. a at 0x7ffdfa9cc470 x = 53. a at 0x7ffdfa9ac440 x = 52. a at 0x7ffdfa98c410 x = 51. a at 0x7ffdfa96c3e0 x = 50. a at 0x7ffdfa94c3b0 x = 49. a at 0x7ffdfa92c380 x = 48. a at 0x7ffdfa90c350 x = 47. a at 0x7ffdfa8ec320 x = 46. a at 0x7ffdfa8cc2f0 x = 45. a at 0x7ffdfa8ac2c0 x = 44. a at 0x7ffdfa88c290 x = 43. a at 0x7ffdfa86c260 x = 42. a at 0x7ffdfa84c230 x = 41. a at 0x7ffdfa82c200 x = 40. a at 0x7ffdfa80c1d0 x = 39. a at 0x7ffdfa7ec1a0 x = 38. a at 0x7ffdfa7cc170 段错误 (核心已转储)

    x = 20的结果

    x = 20. a at 0x7ffcda086210 x = 19. a at 0x7ffcda0661e0 x = 18. a at 0x7ffcda0461b0 x = 17. a at 0x7ffcda026180 x = 16. a at 0x7ffcda006150 x = 15. a at 0x7ffcd9fe6120 x = 14. a at 0x7ffcd9fc60f0 x = 13. a at 0x7ffcd9fa60c0 x = 12. a at 0x7ffcd9f86090 x = 11. a at 0x7ffcd9f66060 x = 10. a at 0x7ffcd9f46030 x = 9. a at 0x7ffcd9f26000 x = 8. a at 0x7ffcd9f05fd0 x = 7. a at 0x7ffcd9ee5fa0 x = 6. a at 0x7ffcd9ec5f70 x = 5. a at 0x7ffcd9ea5f40 x = 4. a at 0x7ffcd9e85f10 x = 3. a at 0x7ffcd9e65ee0 x = 2. a at 0x7ffcd9e45eb0 x = 1. a at 0x7ffcd9e25e80 x = 20. recurse(x) = -20
    最新回复(0)