简体   繁体   English

堆栈溢出错误 java

[英]Stack Overflow Error java

I'm trying to solve a problem that calls for recursive backtracking and my solution produces a stackoverflow error.我正在尝试解决一个需要递归回溯的问题,而我的解决方案会产生 stackoverflow 错误。 I understand that this error often indicates a bad termination condition, but my ternimation condition appears correct.我了解此错误通常表示终止条件不好,但我的终止条件似乎是正确的。 Is there anything other than a bad termination condition that would be likely to cause a stackoverflow error?除了可能导致 stackoverflow 错误的不良终止条件之外,还有什么其他的吗? How can I figure out what the problem is?我怎样才能找出问题所在?

EDIT: sorry tried to post the code but its too ugly..编辑:抱歉试图发布代码,但它太丑陋了..

As @irreputable says, even if your code has a correct termination condition, it could be that the problem is simply too big for the stack (so that the stack is exhausted before the condition is reached).正如@irreputable 所说,即使您的代码具有正确的终止条件,也可能是问题对于堆栈来说太大了(因此堆栈在达到条件之前就已用尽)。 There is also a third possibility: that your recursion has entered into a loop.还有第三种可能:你的递归进入了循环。 For example, in a depth-first search through a graph, if you forget to mark nodes as visited, you'll end up going in circles, revisiting nodes that you have already seen.例如,在通过图进行深度优先搜索时,如果您忘记将节点标记为已访问,您最终会陷入循环,重新访问您已经看到的节点。

How can you determine which of these three situations you are in?您如何确定您处于这三种情况中的哪一种? Try to make a way to describe the "location" of each recursive call (this will typically involve the function parameters).尝试设法描述每个递归调用的“位置”(这通常会涉及 function 参数)。 For instance, if you are writing a graph algorithm where a function calls itself on neighbouring nodes, then the node name or node index is a good description of where the recursive function is.例如,如果您正在编写一个图算法,其中 function 在相邻节点上调用自身,那么节点名称或节点索引很好地描述了递归 function 的位置。 In the top of the recursive function, you can print the description, and then you'll see what the function does, and perhaps you can tell whether it does the right thing or not, or whether it goes in circles.在递归 function 的顶部,您可以打印描述,然后您将看到 function 做了什么,也许您可以判断它是否做对了,或者它是否在循环。 You can also store the descriptions in a HashMap in order to detect whether you have entered a circle.您还可以将描述存储在 HashMap 中,以检测您是否进入了圆圈。

Instead of using recursion, you could always have a loop which uses a stack.您总是可以使用一个使用堆栈的循环,而不是使用递归。 Eg instead of (pseudo-code):例如代替(伪代码):

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

Use:利用:

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

In a nutshell, simulate recursion by saving the state in a local stack.简而言之,通过将 state 保存在本地堆栈中来模拟递归。

As the other fellas already mentioned, there might be few reasons for that:正如其他人已经提到的那样,可能有几个原因:

  • Your code has problem by nature or in the logic of the recursion.您的代码本质上或递归逻辑存在问题。 It has to be a stoping condition, base case or termination point for any recursive function.它必须是任何递归 function 的停止条件、基本情况或终止点。
  • Your memory is too small to keep the number of recursive calls into the stack.您的 memory 太小,无法将递归调用的数量保留在堆栈中。 Big Fibonacci numbers might be good example here.大斐波那契数可能是一个很好的例子。 Just FYI Fibonacci is as follows (sometimes starts at zero):仅供参考,斐波那契如下(有时从零开始):

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

    Fn = Fn-1 + Fn-2 Fn = Fn-1 + Fn-2

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

You can use the -Xss option to give your stack more memory if your problem is too large to fix in the default stack limit size.如果您的问题太大而无法在默认堆栈限制大小中修复,您可以使用 -Xss 选项为您的堆栈提供更多 memory。

If your code is correct, then the stack is simply too small for your problem.如果您的代码是正确的,那么堆栈对于您的问题来说太小了。 We don't have real Turing machines.我们没有真正的图灵机。

There are two common coding errors that could cause your program to get into an infinite loop (and therefore cause a stack overflow):两个常见的编码错误可能导致您的程序进入无限循环(并因此导致堆栈溢出):

  • Bad termination condition不良终止条件
  • Bad recursion call错误的递归调用

Example:例子:

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

Otherwise, your program could just be functioning properly and the stack is too small.否则,您的程序可能只是运行正常而堆栈太小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM