简体   繁体   中英

Java: Recursion causes Stack Overflow Error even though code is correct

I am trying to make a program that goes through a sprite image, and then makes each shape in it a new image. For example, if we took Mario, I want the hat to be one image, the face to be another, and so on. I have gotten my program to work on small 32x32 images, but if I want to run this on a larger image, it causes a Stack Overflow Error. If I was using C++, I would just go about this by clearing the stack after each recursive call, but as far as I know, Java does not let you directly clear the stack. I want my program to run on Windows, Linux and Mac so I thought Java would be the best option, so I don't really want to switch the language I am using. Is there a way to delete whatever was stored on the stack after each recursive call in Java? Here is my code, just in case there is an error with it.

 private void makeShape(int x, int y)
    {
        if(x < 0 || y < 0 || y >= sprite.getHeight() || x >= sprite.getWidth())
        {
            return;
        }
        if(sample == colorData[y][x] && table[y][x])
        {
            tempBlankImage[y][x] = sample;
            table[y][x] = false;
            makeShape(x, y - 1);
            makeShape(x, y + 1);
            makeShape(x - 1, y);
            makeShape(x + 1, y);
        }
        else
        {
            return;
        }

    }

The x and y points are generated from a for loop that goes through the image and checks if a point has been added to a shape, and if not it makes a shape from its surrounding pixels.

UPDATE:

    private int[][] makeShape(int sample, int x, int y)
    {
        int[][] tempBlankImage = blankImage();
        Queue<Point> queue = new LinkedList<Point>();
        queue.add(new Point(x,y));
        while(!queue.isEmpty())
        {
            Point point = queue.remove();
            if(sample == colorData[point.y][point.x] && table[point.y][point.x])
            {
                tempBlankImage[point.y][point.x] = sample;
                table[point.y][point.x] = false;
                if(point.y < sprite.getHeight() -1)
                    queue.add(new Point(point.x, point.y+1));
                if(point.y > 0)
                    queue.add(new Point(point.x, point.y-1));
                if(point.x < sprite.getWidth()-1)
                    queue.add(new Point(point.x+1, point.y));
                if(point.x > 0)
                    queue.add(new Point(point.x-1, point.y));
            }

        }
        queue = null;
        return tempBlankImage;
    }

The Stack Overflow Error has stopped, now I am getting out Out of Memory: Java Heap Space, even though I increased it to 2 GB. I am adding each int[][] to an ArrayList, which I am guessing is the issue. How else can I store the data?

Java is well known for it's automatic well defined and tested memory management system - it is generally not good idea to manage memory on your own even if it is possible (because in some level it actually is).

What will clearing stack give you if the alghoritm execution time will let you get a beard and be able to tell stories about it to your grand children?

Do not make it as recursive - think about some iterative form of an alghoritm. You can for example iterate over all image's pixels and add them to the appropriate image (due to it's color) that will be stored in some HashMap like in this pseudo code

    HashMap<Color, Image> images= new HashMap<Color, Image>();

    for(Pixel pixel : originImage)
        Color color = pixel.getColor();
        images.get(color).put(pixel)

Do not waste your life for bad code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM