Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 递归过程内的第一个过程调用发生堆栈溢出_Java_Recursion_Runtime Error_Stack Overflow - Fatal编程技术网

Java 递归过程内的第一个过程调用发生堆栈溢出

Java 递归过程内的第一个过程调用发生堆栈溢出,java,recursion,runtime-error,stack-overflow,Java,Recursion,Runtime Error,Stack Overflow,由于我理解的一个bug,我得到了一个堆栈溢出错误,但我不理解的是,为什么堆栈溢出发生在递归过程的第一个过程上,而不是在调用递归过程时 在解决数独难题的方法中,这里是递归段(粗体文本是递归调用: System.out.print(""); <= stack overflow occurs here int[] move_quality_sorted_keys = Sorting_jsc.RadixSort_unsigned_1( move_quality ); for

由于我理解的一个bug,我得到了一个堆栈溢出错误,但我不理解的是,为什么堆栈溢出发生在递归过程的第一个过程上,而不是在调用递归过程时

在解决数独难题的方法中,这里是递归段(粗体文本是递归调用:


    System.out.print(""); <= stack overflow occurs here
    int[] move_quality_sorted_keys = Sorting_jsc.RadixSort_unsigned_1( move_quality );
    for( int xPossibleMove = 1; xPossibleMove <= ctPossibleMoves; xPossibleMove++ ){
        int xMove = move_quality_sorted_keys[ctPossibleMoves - xPossibleMove + 1];
        int[][] new_grid = new int[10][10];
        for( int xRow = 1; xRow <= 9; xRow++ )
            for( int xColumn = 1; xColumn <= 9; xColumn++ )
                new_grid[xRow][xColumn] = grid[xRow][xColumn];
        new_grid[move_row[xMove]][move_column[xMove]] = move_value[xMove];
        int[][] solution = solveSudokuGrid( new_grid );
        if( solution != null ) return solution;
    }

我希望堆栈溢出发生在对solveSudokuGrid的调用上,而不是在print语句上。为什么呢?

因为此时超出了堆栈界限


似乎System.out.println最终会调用BufferedWriter.write,这也是一个递归函数,最终会导致堆栈溢出。

这样看:每次调用System.out.println时,您都会推4(或更多)如错误中所示,堆栈顶部的其他堆栈帧。然后,在递归调用自己的函数之前,这些帧会弹出堆栈。因此,堆栈的深度如下所示:

  • 你的代码,1级
  • println,5级
  • 你的代码,2级
  • println,6级
  • 你的代码,3级
  • println,7级
  • 你的代码,n级
  • println,n+4级
  • 你的代码,n+1级
假设每个级别占用相同数量的堆栈内存(这实际上不是真的,但对于这种分析来说可能足够接近),很明显,对于堆栈大小的任何特定限制,println代码都会首先突破它


实际上需要做的就是让另一个过程在堆栈上使用比你的过程更多的内存,这总是会发生的。如果它使用更少的内存,它可能仍然会发生(因为对于任何给定的级别,它都是在你的代码之前被调用的),可能因为println调用只是为了演示这一点,所以您在下一行中调用的基数排序代码之前触发了该行为。它可能比您自己的方法使用更多的堆栈空间(这似乎很有可能;您只有6个局部变量,并且大多数表达式都非常简单).

你到底在那里打印什么?@AndyFaizan没什么,print语句只是用来证明堆栈溢出发生在递归过程内部的第一次调用上,而不是在递归过程本身的调用上。堆栈爆炸时有多深?堆栈太大时会报告错误要进一步扩展。如果例程中的第一条语句是一个print调用(它进一步扩展了堆栈),则会检测到错误。是的,除非一帧
solveSudokuGrid
所需的堆栈量大于
print
调用的4个(或更多)方法所需的堆栈量(不太可能)然后在
print
调用中始终会检测到故障。
Exception in thread "main" java.lang.StackOverflowError
    at java.io.BufferedWriter.write(BufferedWriter.java:221)
    at java.io.Writer.write(Writer.java:157)
    at java.io.PrintStream.write(PrintStream.java:525)
    at java.io.PrintStream.print(PrintStream.java:669)
    at Euler100.solveSudokuGrid(Euler100.java:2458)
    at Euler100.solveSudokuGrid(Euler100.java:2467)
    at Euler100.solveSudokuGrid(Euler100.java:2467)
    at Euler100.solveSudokuGrid(Euler100.java:2467)
    at Euler100.solveSudokuGrid(Euler100.java:2467)
    at Euler100.solveSudokuGrid(Euler100.java:2467)
    at Euler100.solveSudokuGrid(Euler100.java:2467)
    at Euler100.solveSudokuGrid(Euler100.java:2467)
    at Euler100.solveSudokuGrid(Euler100.java:2467)
    at Euler100.solveSudokuGrid(Euler100.java:2467)