Search code examples
javainputerror-handlingstack-overflow

How can I Avoid a Stack Overflow While Still Having a Continuous Loop?


I have a simple program (code at bottom) that reads user input and then spits it back out. I know there maybe other solutions to my problem, but I want to use something like this because it will be useful in future programs. I am running into Stack overflow Problems. I already read this topic:

-What is a StackOverflowError? -

and I have read the top few answers, but the problem is that I want a continuous loop, because it is the purpose of the program. I was wondering if there was any way to clear my "stack" so that I could keep looping. I don't need to keep any data once I finish each run through, If that helps.

It works fine if I change line 15 from:

for(int y=0;y<System.in.available();++y)

to:

for(int y=0;y<10;++y)

but doing that puts a hard limit on the amount of characters it can read, and I don't want that. And also, if possible, I would prefer to continue using the (char)System.in.read() method of taking input.

My program looks like this:

package main;

import java.io.IOException;

public class Root 
{   
    public static void main(String[] args)
    {
        new Root();
    }

    public Root()
    {
        try{
            for(int y=0;y<System.in.available();++y)
            {
                try 
                {
                    System.out.print((char)System.in.read());
                } 
                catch (IOException exep)
                {
                    System.out.print(exep.getLocalizedMessage());
                }
            }
        }
        catch(IOException exep)
        {
            System.out.println(exep.getLocalizedMessage());
        }
        new Root();
    }

}

Solution

  • You seem to be creating Root objects but not really using them. The boundless recursion will keep pushing stack frames on the stack for each run of available characters, eventually ending up with a stack overflow exception -- Java doesn't do tail-call optimisation (TCO).

    Why not change your Root constructor to:

    public Root()
    {
        while (true) {
            try{
                for(int y=0;y<System.in.available();++y)
                {
                    try 
                    {
                        System.out.print((char)System.in.read());
                    } 
                    catch (IOException exep)
                    {
                        System.out.print(exep.getLocalizedMessage());
                    }
                }
            }
            catch(IOException exep)
            {
                System.out.println(exep.getLocalizedMessage());
            }
        }
    }