Java 递归过程内的第一个过程调用发生堆栈溢出
由于我理解的一个bug,我得到了一个堆栈溢出错误,但我不理解的是,为什么堆栈溢出发生在递归过程的第一个过程上,而不是在调用递归过程时 在解决数独难题的方法中,这里是递归段(粗体文本是递归调用: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
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调用只是为了演示这一点,所以您在下一行中调用的基数排序代码之前触发了该行为。它可能比您自己的方法使用更多的堆栈空间(这似乎很有可能;您只有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)