简体   繁体   中英

Java - StackOverFlow error

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?

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()?

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 (ie 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.


PS If you're feeling down, here is a REAL StackOverFlow error!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM