遞迴呼叫的棧溢位

2021-09-23 20:31:31 字數 3730 閱讀 1066

**如下:

#include #include int recurse(int x) 

int main(int argc, char *ar**)

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的記憶體,一直呼叫下去,當陣列的位址破壞了返回位址時,就不能再呼叫遞迴函式了,這樣一來,程式就不能再往下進行了,就出現 段錯誤 (核心已轉儲)的錯誤了,但是如果呼叫次數較少時,就可以避免這個錯誤了.

啟示:我們在寫遞迴函式時,一定要注意遞迴函式的所佔記憶體,如果所佔記憶體較大,就一定得注意遞迴呼叫的次數,控制好遞迴結束條件.

遞迴和棧溢位。

遞迴確實是很多演算法的基礎思想。但外部因素導致遞迴會棧溢位。但卻是不甘心如此簡練的有效的演算法,放棄不用。所以一般有2中方式來使用大資料的遞迴思路 1 用棧型別放入引數,模擬遞迴呼叫。2 把大資料分割為一批適中的資料,就可以直接使用遞迴函式。用快速排序,測試並總結了下。1 本例大概 排序30000個...

棧溢位和棧記憶體溢位

棧記憶體溢位是指使用者棧的大小最多為8 10mb,分配超過棧大小的變數則會導致棧記憶體溢位。如char c 1024102411 11mb 棧溢位指的是程式向棧中某個變數中寫入的位元組數超過了這個變數本身所申請的位元組數,因而導致與其相鄰的棧中的變數的值被改變。如char c 10 memset c...

棧溢位,記憶體溢位

對於一台伺服器而言,每乙個使用者請求,都會產生乙個執行緒來處理這個請求,每乙個執行緒對應著乙個棧,棧會分配記憶體,此時如果請求過多,這時候記憶體不夠了,就會發生棧記憶體溢位。棧溢位是指不斷的呼叫方法,不斷的壓棧,最終超出了棧允許的棧深度,就會發生棧溢位,比如遞迴操作沒有終止,死迴圈。可以把記憶體比作...