簡體   English   中英

堆棧溢出錯誤 java

[英]Stack Overflow Error java

我正在嘗試解決一個需要遞歸回溯的問題,而我的解決方案會產生 stackoverflow 錯誤。 我了解此錯誤通常表示終止條件不好,但我的終止條件似乎是正確的。 除了可能導致 stackoverflow 錯誤的不良終止條件之外,還有什么其他的嗎? 我怎樣才能找出問題所在?

編輯:抱歉試圖發布代碼,但它太丑陋了..

正如@irreputable 所說,即使您的代碼具有正確的終止條件,也可能是問題對於堆棧來說太大了(因此堆棧在達到條件之前就已用盡)。 還有第三種可能:你的遞歸進入了循環。 例如,在通過圖進行深度優先搜索時,如果您忘記將節點標記為已訪問,您最終會陷入循環,重新訪問您已經看到的節點。

您如何確定您處於這三種情況中的哪一種? 嘗試設法描述每個遞歸調用的“位置”(這通常會涉及 function 參數)。 例如,如果您正在編寫一個圖算法,其中 function 在相鄰節點上調用自身,那么節點名稱或節點索引很好地描述了遞歸 function 的位置。 在遞歸 function 的頂部,您可以打印描述,然后您將看到 function 做了什么,也許您可以判斷它是否做對了,或者它是否在循環。 您還可以將描述存儲在 HashMap 中,以檢測您是否進入了圓圈。

您總是可以使用一個使用堆棧的循環,而不是使用遞歸。 例如代替(偽代碼):

function sum(n){
  if n == 0, return 0
  return n + sum(n-1)
}

利用:

function sum(n){
  Stack stack
  while(n > 0){
    stack.push(n)
    n--
  }
  localSum = 0
  while(stack not empty){
    localSum += stack.pop()
  }
  return localSum
}

簡而言之,通過將 state 保存在本地堆棧中來模擬遞歸。

正如其他人已經提到的那樣,可能有幾個原因:

  • 您的代碼本質上或遞歸邏輯存在問題。 它必須是任何遞歸 function 的停止條件、基本情況或終止點。
  • 您的 memory 太小,無法將遞歸調用的數量保留在堆棧中。 大斐波那契數可能是一個很好的例子。 僅供參考,斐波那契如下(有時從零開始):

    1,1,2,3,5,8,13,...

    Fn = Fn-1 + Fn-2

    F0 = 1, F1 = 1, n>=2

如果您的問題太大而無法在默認堆棧限制大小中修復,您可以使用 -Xss 選項為您的堆棧提供更多 memory。

如果您的代碼是正確的,那么堆棧對於您的問題來說太小了。 我們沒有真正的圖靈機。

兩個常見的編碼錯誤可能導致您的程序進入無限循環(並因此導致堆棧溢出):

  • 不良終止條件
  • 錯誤的遞歸調用

例子:

public static int factorial( int n ){
    if( n < n ) // Bad termination condition
        return 1;
    else
        return n*factorial(n+1); // Bad recursion call
}

否則,您的程序可能只是運行正常而堆棧太小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM