Java不一致的堆栈溢出 [英] Java Inconsistent Stack Overflow

查看:65
本文介绍了Java不一致的堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在为AP计算机科学课程完成最后的项目,并正在修改AP Picture Lab来完成它(所有源代码都可以在

I've been working on my final project for my AP Computer Science class and am modifying the AP Picture Lab to do it (all of the source code is available at https://github.com/jvperrin/ap-picture-lab).

对于我的项目的一部分,我实现了深度优先搜索,以使目标像素附近的黑色像素变为黑色.但是,似乎每隔一次我运行该程序,就会收到堆栈溢出错误或程序运行正常.我有这个问题吗?它与Java存储堆栈内存的方式有关吗?

For one portion of my project, I implement a depth first search to get adjacent pixels to the target pixel that are black. However, it seems like every other time I run the program I either get a stack overflow error or the program works perfectly. Is there a reason I'm getting this problem? Does it have to do with how Java stores stack memory?

错误消息

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类:

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的主要方法).

(I have a main method elsewhere that instantiates a ZPicture and calls findletters).

推荐答案

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

The StackOverFlowError is caused by the recursive call (which isn't even necassary). The cause for the error is pretty simple: for every element in the stack, the algorithm makes another recursive call. If the area of black pixels is large enough, the number of adjacent black pixels will exceed the stack-size, causing the StackOverFlowError. Good news: the recursive call doesn't make any sense here, since you already use a stack. Simply remove it, and the code should work like a charm.

这篇关于Java不一致的堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆