Search code examples
javaandroidandroid-fragmentsstack-overflow

stack=java.lang.StackOverflowError: stack size 8MB


I'm getting this StackOverFlow error, i understand it fully, but the issue is im not dealing with big data, So how can this error be produced ?

I have an activity, Framelayout, a fragment, 3 options.

In the fragment, when you click on one of those options, it re-create the fragment and put random numbers, the MAX is 15, So its not that big, this error happens when the user click so fast on the options which cause this overflow.

This is the code for generating, any ideas about "enhancing" it ? i don't know if this code is a bad practice for momery using.

private static List<Integer> SavedNumbers;

public static void SetupSavedNumbersLIst(){
    SavedNumbers = new ArrayList<>();
}


static List<Integer> range;
private static void AddDiff(int mMAX){
    range = new ArrayList<>();
    for(int i = 0 ; i < mMAX ; i++){
        range.add(i);
    }

    range.removeAll(SavedNumbers);
}

private static int ReturnIfDuplic(int mMAX){
    AddDiff(mMAX);
    return new Random().nextInt(range.size());
}


public static int ReturnUniqueSavedNumber(int mMAX){
    int Random = ReturnRandom(mMAX);
    if(SavedNumbers != null && SavedNumbers.size() > 0) {
        if(DoesSavedNumberExist(Random)){
            return ReturnIfDuplic(mMAX);
        } else {
            SavedNumbers.add(Random);
            return Random;
        }
    } else if (SavedNumbers != null && SavedNumbers.size() == 0){
        SavedNumbers.add(Random);
        return Random;
    } else if( SavedNumbers == null){
        SetupSavedNumbersLIst();
        return ReturnUniqueSavedNumber(mMAX);
    } else {
        return 1;
    }
}

private static boolean DoesSavedNumberExist(int Number){
    for(int s: SavedNumbers){
        if(Number == s)
            return true;
    }
    return false;
}

private static int ReturnRandom(int mMAX){
    return new Random().nextInt(mMAX);
}

Solution

  • This line is recursing if you happen to random the same number you have already saved:

    if(DoesSavedNumberExist(Random)){
        return ReturnUniqueSavedNumber(mMAX);
    } 
    

    If you have already saved 1-15, and your max is 15 this will guarantee a stack-overflow as it will never satisfy the if statement. This is also generally a bad approach of "random number no good, just try again", since as you add more and more numbers you will add more and more recursions. A better approach may be to have the random number used as an index into the possible numbers that are left to choose.