Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - StackOverFlow error

So thanks to @fireshadow52, I've managed to come up with this script that sins args[0]. However, it spits out a StackOverFlow error. What is this, and how (if possible) would you spot them?

class SIN {
    public static void main(String[] args) {
        double result = sin(args[0]);
    }
    public double sin(x) { Math.sin(x); return sin(x); }
}
like image 720
Tony Avatar asked Jan 18 '23 22:01

Tony


2 Answers

I'm not sure why it is giving a stackoverflow error but this is not valid java.

The sin method doesn't declare a type of the input parameter. The string args need to be converted to double for Math.sin to work. The class name breaks java coding convention (not an error). The errors should have been detected by a java compiler. Did the compiler throw any errors?

like image 187
Brett Walker Avatar answered Jan 30 '23 05:01

Brett Walker


An excerpt from an answer to a similar question...

Parameters and local variables are allocated on the stack (with reference types the object lives on the heap and a variable references that object). The stack typically lives at the upper end of your address space and as it is used up it heads towards the bottom of the address space (ie towards zero).

Your process also has a heap, which lives at the bottom end of your process. As you allocate memory this heap can grow towards the upper end of your address space. As you can see, there is the potential for the heap to "collide" with the stack (a bit like techtonic plates!!!).

A Stack Overflow error means that the stack (your method) overflowed (executed itself so many times that it crashed). Stack Overflow errors usually result from a bad recursive call.

In general, if your method name doesn't have the keyword void in it, make sure the return value isn't the same as the method name. Otherwise, the stack will overflow, crashing your program. Just replace these lines:

Math.sin(x);
return sin(x);

...with this line...

return Math.sin(x);

...and you should be good to go!

Sometimes in can be a bit tricky to find out when a program will crash:

Q: Will this program crash? If so, why?

public void MultiplyByNintyNine(byte num) {
    MultiplyByNintyNine(num * 99);
}

A: Actually, this could crash for two reasons:

  1. The number could get so large that the JVM can't handle it.

  2. The function could call itself so many times that the JVM crashes (i.e. a Stack Overflow error).

The latter case is the more reasonable; even though the method doesn't actually return anything, the method is still called.

In some cases, it is perfectly OK to return the method name. Just make sure you have a terminating condition if you do, though! Here is an example similar to yours (that doesn't crash):

import java.io.*;
//class declaration here

public static void main(String[] args) {
    System.out.println(guessTheNumber());
}

public String guessTheNumber() {
    int guess;
    System.out.print("Guess the number:_");
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    try {
        guess = Integer.parseInt(br.readLine());
    } catch (NumberFormatException e) {
        System.err.println("You didn't guess a number.");
        guessTheNumber();
    } catch (IOException e) {
        System.err.println("An unexpected error occured. Please try again.");
        guessTheNumber();
    }
    if (guess == 4) {
        return "YAY! You get a prize!";
    } else {
        System.err.println("WAAHH! You get to guess again!");
        guessTheNumber();
    }
}

Warning: The only way to stop this code (from the code itself) is to enter 4.

In the above case, the terminating condition occurs when a user enters an actual number and that number is 4.


P.S. If you're feeling down, here is a REAL StackOverFlow error!

like image 43
fireshadow52 Avatar answered Jan 30 '23 05:01

fireshadow52