Java不一致堆栈溢出

时间:2015-05-08 02:13:51

标签: java image exception awt stack-overflow

我一直致力于我的AP计算机科学课程的最终项目,并正在修改AP图片实验室(所有源代码可在https://github.com/jvperrin/ap-picture-lab获得)。

对于我项目的一部分,我实现了深度优先搜索,以获得黑色目标像素的相邻像素。但是,似乎每次运行程序时我都会遇到堆栈溢出错误或程序运行完美。我有没有理由得到这个问题?是否与Java存储堆栈内存有关?

错误消息

Exception in thread "main" java.lang.StackOverflowError
at java.awt.image.ComponentColorModel.getRGB(Unknown Source)
at java.awt.image.BufferedImage.getRGB(Unknown Source)
at SimplePicture.getBasicPixel(SimplePicture.java:300)
at Pixel.getAlpha(Pixel.java:86)
at Pixel.setBlue(Pixel.java:296)
at ZPicture.depthFirstSearch(ZPicture.java:50)
at ZPicture.depthFirstSearch(ZPicture.java:73)
at ZPicture.depthFirstSearch(ZPicture.java:73)
at ZPicture.depthFirstSearch(ZPicture.java:73)
....

ZPicture Class:

    import java.util.ArrayList;
import java.util.Stack;

public class ZPicture extends SimplePicture {
    protected Pixel[][] pixels;
    protected boolean[][] checked;
    protected Stack<Pixel> stack;
    // a multidimensional array list?!?!
    //letters is the pixels in letters
    protected ArrayList<ArrayList<Pixel>> letters;
    //chars are the key points in letters
    protected ArrayList<ZChar> chars;
    protected final int BLACK = 30;
    protected final int SIZE = 10;

    public ZPicture(String fileName) {
        super(fileName);
        pixels = this.getPixels2D();
        checked = new boolean[pixels.length][pixels[0].length];
        stack = new Stack<Pixel>();
        letters = new ArrayList<ArrayList<Pixel>>();
        letters.add(new ArrayList<Pixel>());
        chars = new ArrayList<ZChar>();
    }

    // Z METHODS
    public void findLetters() {
        // Y
        for (int row = 0; row < pixels.length; row++) {
            // X
            for (int col = 0; col < pixels[0].length; col++) {
                Pixel p = pixels[row][col];
                if (isBlack(p)) {
                    stack.push(p);
                    depthFirstSearch();
                }
            }
        }
        sortLetters();
        findPoints();
        printLetters();
    }

    protected void depthFirstSearch() {
        // base case - if stack has elements
        if (!stack.isEmpty()) {
            Pixel p = stack.pop();
            checked[p.getY()][p.getX()] = true;
            letters.get(letters.size() - 1).add(p);
            p.setBlue(255);

            // get surrounding pixels
            Pixel pt = pixels[p.getY() - 1][p.getX()];
            Pixel pr = pixels[p.getY()][p.getX() + 1];
            Pixel pb = pixels[p.getY() + 1][p.getX()];
            Pixel pl = pixels[p.getY()][p.getX() - 1];

            // if pixel is black and unchecked, add to stack
            if (isBlack(pt)) {
                stack.push(pt);
            }
            if (isBlack(pr)) {
                stack.push(pr);
            }
            if (isBlack(pb)) {
                stack.push(pb);
            }
            if (isBlack(pl)) {
                stack.push(pl);
            }

            // recursion
            depthFirstSearch();
        } else {
            System.out.println("New Letter: " + letters.size());
            // note: the final letter is always empty
            letters.add(new ArrayList<Pixel>());
        }
    }

    protected boolean isBlack(Pixel p) {
        if (p.getBlue() < BLACK && p.getRed() < BLACK && p.getGreen() < BLACK
                && checked[p.getY()][p.getX()] == false) {
            return true;
        }
        return false;
    }

}

(我在其他地方有一个实例化ZPicture并调用findletters的主方法。)

1 个答案:

答案 0 :(得分:3)

StackOverFlowError是由递归调用引起的(甚至不需要)。导致错误的原因非常简单:对于堆栈中的每个元素,算法都会进行另一次递归调用。如果黑色像素的面积足够大,则相邻黑色像素的数量将超过堆栈大小,从而导致StackOverFlowError。好消息:递归调用在这里没有任何意义,因为你已经使用了堆栈。只需删除它,代码应该像魅力一样。

相关问题