1

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);
}
Jaeger
  • 1,646
  • 8
  • 27
  • 59
  • ... there is a chance that new Random().nextInt() would generate the same number for eternal life ... just build a list of ints that you need and shuffle it http://ideone.com/XJRRba – Selvin Nov 17 '16 at 17:31
  • From the code, i can see it as an alternative approach for generating random numbers in a range without duplicates, right? please keep in mind that this method (generate random number) is called every fragment re-creating, so each time its called, only one random number will be generated. – Jaeger Nov 17 '16 at 17:34
  • but here you just generate the all numbers sequence at once and just pick next, you can always save the sequence – Selvin Nov 17 '16 at 17:35
  • https://ideone.com/WPSwhR , 2, 3, 1, 0, Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4 – Jaeger Nov 17 '16 at 17:44
  • Oops, my mistake, i should take a rest :D – Jaeger Nov 17 '16 at 17:50
  • After trying out, still having the issue in my app, out of bounds, and there's a big lag when re-creating a fragment, a lag that didn't exist first. – Jaeger Nov 17 '16 at 18:08
  • I don't have time to write a whole solution based on your new code, but some random notes. You shouldn't need saved numbers anymore, just remove them from the collection of available numbers. Don't re-create available numbers every time, you should only need to do this once. And the returnIfDuplicat method looks suspect, with the method I propose, there should be no chance of ever getting a duplicate, the method shouldn't be necessary. If I have time later tonight I can write a more complete solution. – Kevin DiTraglia Nov 17 '16 at 18:17
  • As a solution, I've modified my code and made it better and fixed that issue of OverFlow, for your code i'd love to use it, as it's way shorter, but i don't know about if it's better from code POV or not. – Jaeger Nov 17 '16 at 19:00

3 Answers3

6

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.

Kevin DiTraglia
  • 25,746
  • 19
  • 92
  • 138
  • I thought about that, for taking the possible left numbers, it would be hard to Random generate them, as i may need to put, for example " return 5 " along with with a Switch function. – Jaeger Nov 17 '16 at 17:11
  • Think about an array of the remaining numbers, then random a number between 0 and the array length and return that value from the array – Kevin DiTraglia Nov 17 '16 at 17:14
  • To do such a thing, first i need to make a new Int List, and fill it with the `max` number, and then find what left like this example : http://stackoverflow.com/questions/13286008/find-out-the-elements-of-an-arraylist-which-is-not-present-in-another-arraylist , and randomize it, but the question is, to create an array of int, i need to loop, is that loop will make it a bad practice also ? – Jaeger Nov 17 '16 at 17:23
0

i encounter with same problem Stack Size 8MB. when i hit my add item api got the same error . i thought it was happening at the time of getting values from the edit text. so that i change my way and get the values in my inIT(); before service call

inIT()  
sys = input_Systolic.getText().toString();
                dys = input_Diastolic.getText().toString();
                _date = dateView.getText().toString();
                tim = time.getText().toString();

Retrofit call

 HashMap<String, Object> pMap = new HashMap<>();
         pMap.put("user_id",loginStatusModal.getUser_id());
         pMap.put("relative_id",rel_id);
         pMap.put("systolic",sys);
         pMap.put("diastolic",dys);
         pMap.put("report_date",_date);
         pMap.put("report_time",tim);

with using this i solve my stack size 8mb error.

Kunal Nikam
  • 79
  • 1
  • 11
0

I had the same problem when I was trying to pass many values using intent.putExtra().

I resolved this by saving all the data in shared preferences. You can then access any fragments or activities required in the application in a later part.

Refer this question to learn more about saving data using shared preferences.

Aido
  • 1,524
  • 3
  • 18
  • 41
Rohan
  • 60
  • 1
  • 5