4

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); }
}
3
  • 5
    You can't even call the sin() method from the main() since sin() is not static. Otherwise it produces the StackOverflowError because your're in a endless loop since you're calling the sin() when returning. Commented Aug 21, 2011 at 1:49
  • 2
    Not to mention the x has no type. Commented Aug 21, 2011 at 1:52
  • Why not just do double result = Math.sin(Double.parseDouble(args[0])); Commented Aug 21, 2011 at 2:22

4 Answers 4

3

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?

Sign up to request clarification or add additional context in comments.

Comments

2

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!

4 Comments

on the MultiplyByNintyNine it won't crash because of to big of a value, floats cleanly overflows to infinity and Float.POSITIVE_INFINITY*99==Float.POSITIVE_INFINITY
@ratchet freak True, true. I'll change the answer.
and byte just wraps around so (byte)(127+1)==(byte)-128
@ratchet freak Well you get the gist; you don't have to have a return stament to execute a method.
2

Your sin method is calling itself, so this will continue indefinately until you reach the call stack limit where you get your exception. Why don't you just return Math.sin()?

Comments

2

Your code is close, but the sin function should really be

public double sin(double x) {
    return Math.sin(x);
}

Notice that we can simply return the value of Math.sin(x). No need to return `sin(x)~ afterwards.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.