简体   繁体   中英

Why am I receiving a Stack overflow error?

The following code simulates finding the closest pair but when I generate a random amount of pairs greater than 250 it throws a stack overflow error. But 250 pairs and any even amount under seem to work fine. Any ideas?

The error occurs at the recursive call of ComparePoints under the if statement.

public class Divide {

    Point2D closest1;
    Point2D closest2;
    double Distance = Double.MAX_VALUE;

    public Divide(Point2D[] RandArray){
        SortArray s = new SortArray();
        RandArray = s.SortPointsX(RandArray);
        SplitAndConquer(RandArray);
    }

    private double ComparePoints(Point2D a, Point2D b, Point2D[] s, 
                int CurrentPoint, int NextPoint){
            if(s[CurrentPoint] != null && s[NextPoint] != null){
                if (Distance > a.distance(b) && 
                        (a.getX() != b.getX() || a.getY() != b.getY())){
                    Distance = a.distance(b);
                    closest1 = new Point2D.Double(a.getX(), a.getY());
                    closest2 = new Point2D.Double(b.getX(), b.getY());
                }
                if (NextPoint == (s.length - 1)){
                    NextPoint = s.length - ((s.length - 1) - CurrentPoint);
                    CurrentPoint++;
                }
                if (CurrentPoint != (s.length - 1)){
                    if (NextPoint != (s.length - 1)){
                    NextPoint++;
                    ComparePoints(s[CurrentPoint], s[NextPoint],
                            s, CurrentPoint, NextPoint);
                    }
                }
                if (CurrentPoint == (s.length - 1)){
                    CurrentPoint = 0;
                    NextPoint = 0;
                }
            }
         return Distance;
    }

    private void SplitAndConquer(Point2D[] RandArray){
        double median = RandArray[RandArray.length/2].getX();
        int countS1 = 0;
        int countS2 = 0;
        boolean exact = false;
        int CurrentPoint = 0;
        int NextPoint = 0;
        Point2D[] s1 = new Point2D[RandArray.length/2];
        Point2D[] s2 = new Point2D[RandArray.length/2];

        for (int i = 0; i < RandArray.length; i++){

            if (RandArray[i].getX() < median){
                s1[countS1] = RandArray[i];
                countS1++;
            }
            else if (RandArray[i].getX() > median){
                s2[countS2] = RandArray[i];
                countS2++;
            }
            else if (RandArray[i].getX() == median && exact == false){
                s2[countS2] = RandArray[i];
                exact = true;
                countS2++;
            }
            else if (RandArray[i].getX() == median && exact == true) {
                s1[countS1] = RandArray[i];
                exact = false;
                countS2++;
            }
        }

        if (s1[0] != null && s1[1] != null){
            Distance = ComparePoints(s1[0], s1[1], s1,
                    CurrentPoint, NextPoint);
            Distance = ComparePoints(s2[0], s2[0], s2,
                    CurrentPoint, NextPoint);
            }else{
                System.out.println
                ("One of the subsets does not contain enough points!");
            }
        CheckMid(RandArray, Distance, median, CurrentPoint, NextPoint);
        PrintClosest();
        }

    private void PrintClosest() {
        System.out.println("The closest pair found using Divide "
                + "And Conquer is at ("
                + closest1.getX() + " " + closest1.getY() + "), and (" 
                + closest2.getX() + " " + closest2.getY() + ")");
        System.out.println("The distance between the pairs is: " + Distance);

    }

    private void CheckMid(Point2D[] randArray, double d, double m,
            int current, int next) {
        int MidCount = 0;
        Point2D[] MidArray = new Point2D[randArray.length];
        for(int i = 0; i < randArray.length; i++){
            if(randArray[i].getX() > (m - d) && 
                    randArray[i].getX() < (m + d)){
                MidArray[MidCount] = randArray[i];
                MidCount++;
            }
        }
        if (MidArray[0] != null && MidArray[1] != null){
        ComparePoints(MidArray[0], MidArray[1], MidArray,
                current, next);
        }
    }
}

Sounds like you're exceeding the the amount of stack memory allocated for your program. You can change the stack size with the -Xss option. Eg java -Xss 8M to change stack size to 8MB and run your program.

Internally Java has call stack, that stores the method calls as stack frames. And it process these method calls (frames) in LIFO manner. when a new thread is created (in your case a main thread) a fixed amount of stack and heap memory is allocated to that thread. So whenever the call stack gets exhausted we get a stackoverflow error. In your case the number of recursive calls has exceeded the size of call stack, and so you are getting the Error.

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