So thanks to @fireshadow52, I've managed to come up with this script that sin
s 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); }
}
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?
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:
The number could get so large that the JVM can't handle it.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With