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

rseugnpd  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(412)

我得到了一个堆栈溢出错误,由于一个错误,我明白,但我不明白的是,为什么堆栈溢出是发生在第一个过程中的递归过程,而不是在调用递归过程。
在解决数独难题的方法中,这里是递归段(粗体文本是递归调用:

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;
    }

堆栈溢出错误如下(请注意,它发生在system.out.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)

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

nwlls2ji

nwlls2ji1#

这样看:每次你打电话 System.out.println 如错误中所示,将4个(或更多)额外的堆栈帧推到堆栈顶部。然后在递归调用自己的函数之前,这些函数会从堆栈中弹出。因此,堆栈的深度如下所示:
你的代码,1级
打印,5级
你的代码,2级
打印,6级
你的代码,3级
打印,7级
...
你的代码,n级
println,n+4级
你的代码,n+1级
...
假设每个级别占用相同的堆栈内存量(这实际上不是真的,但对于这种分析来说可能足够接近),很明显,对于堆栈大小的任何特定限制,println代码都会首先突破它。
实际上所需要做的就是让另一个过程在堆栈上使用比您的过程更多的内存,这将一直发生。如果它使用较少的代码,则仍然可能发生这种情况(因为对于任何给定的级别,它都是在代码之前调用的),而且可能由于println调用只是为了演示这一点,所以您在下一行中调用的基数排序代码之前就触发了这种行为。它可能比您自己的方法使用更多的堆栈空间(这似乎很有可能;只有6个局部变量,大多数表达式都非常简单)。

mfpqipee

mfpqipee2#

因为你超过了那一点的堆栈限制。此处为wiki
似乎system.out.println最终会调用bufferedwriter.write,这也是一个递归函数,最终会导致堆栈溢出。

相关问题