Start learning free

LESSON 118 OF 348 · WHILE LOOPS & FOR LOOPS

Infinite While Loops in Kotlin: Causes and Fixes

Lesson Read the full explanation

Loops bring great power but also great responsability. The biggest danger when using loops is writing an infinite loop.

An infinite loop is a loop that never terminates. For example, if we forget to increment i in our previous example:

var i = 1
while (i < 5) {
	println(i)
	// i++ => forgot this
}

This program will never terminate as i will always have value 1 and thus the condition i < 5 will always be satisfied.

The program would basically print 1 forever never exiting the while loop.


Pro Tip:

As programmers, we want to make sure we never write infinite loops as they make our program run forever and completely unusable.


Assignment
Follow the Coding Tutorial and practice with infinite while loops!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 1
    Ctrl + Enter to check

    KOTLIN · WHILE LOOPS & FOR LOOPS

    Infinite While Loops in Kotlin, explained

    What an infinite loop is

    A while loop repeats its body for as long as its condition is true. If nothing inside the body can ever make the condition false, the loop never ends. That is an infinite loop: the program keeps running, usually printing the same thing again and again, and never reaches the code after the loop.

    The classic cause is forgetting to update the variable the condition depends on:

    var i = 1
    while (i < 5) {
        println(i)
        // forgot i++ here
    }
    

    The variable i starts at 1 and never changes, so i < 5 is true on every check. The program prints 1 forever. A loop like this makes a program unusable, so every loop you write needs a path to a false condition.

    Three questions to ask about any while loop

    1. What does the condition depend on? Name the variable, or variables, it reads.
    2. Does the body change them? If no statement in the body touches those variables, the loop cannot end by itself.
    3. Do they change in the right direction? A counter that must reach a limit has to move toward that limit. A condition like i < 5 with i-- in the body moves away from the limit and never stops.

    A fourth cause is subtler, and it is the one this lesson's exercise is about: the variable changes in the right direction but jumps over the value the condition is waiting for.

    The exercise: odd numbers from 15 down to 1

    The starting program should print 15, 13, 11, and so on down to 1, and then stop:

    var counter = 15
    while (counter != 0) {
        println(counter)
        counter -= 2
    }
    

    Instead it prints the right numbers and then keeps going. Follow counter through the last few passes:

    Value of counterIs counter != 0 true?What happens
    3yesprints 3, becomes 1
    1yesprints 1, becomes -1
    -1yesprints -1, becomes -3
    -3yesprints -3, and so on

    Starting at 15 and subtracting 2 only ever produces odd numbers. Zero is even, so the counter steps over it, and the condition counter != 0 stays true for every value after that. The loop is waiting for an exact value that it will never hit.

    Step by step

    1. Find the mistake. The body is fine: it prints the counter and moves it down by 2. The problem is the condition, which tests for one exact value.
    2. Describe the real stopping rule. The loop should run while the counter is still positive. The last value that should print is 1, and the next value, -1, should end the loop.
    3. Replace != with a comparison that checks a range. counter > 0 is true for 15 down to 1 and false for -1, so the loop stops right after printing 1.

    The solution in Kotlin

    var counter = 15
    while (counter > 0) {
        println(counter)
        counter -= 2
    }
    

    The output is 15, 13, 11, 9, 7, 5, 3, 1, each on its own line, and then the program continues past the loop.

    A few Kotlin details here:

    • var is required. A val cannot be reassigned, so counter -= 2 only compiles because counter is declared with var.
    • counter -= 2 is shorthand for counter = counter - 2.
    • Whole numbers wrap, they do not stop. A Kotlin Int has 32 bits. If a loop kept counting up past Int.MAX_VALUE (2147483647), the value would wrap around to the most negative number instead of failing. This can turn a loop that "should" end into one that runs for a very long time.

    Why a range check is safer than an exact match

    Comparing with != or == works only when the counter is certain to land on the target value. That depends on the starting value, the step and the target all lining up, and a small change to any of them breaks it. For example, with counter != 0 the loop stops if the start is 16 (16, 14, ... 2, 0) but runs forever if the start is 15. Conditions that use <, <=, > or >= ask "have we gone far enough?", and they stay correct when the counter jumps past the limit.

    Other common ways to loop forever

    • Updating the wrong variable. The body changes j while the condition reads i.
    • Moving in the wrong direction. i++ in a loop that waits for i to fall below a limit.
    • Update behind a condition. The step lives inside an if that is sometimes false, so on some passes the counter does not change.
    • A condition that is always true. while (true) is a loop without an end on purpose. It is only correct when something inside the loop, such as a break, can leave it.

    What to do when a program will not stop

    Stop the program, then read the loop with a pencil: write the variable's value for the first three passes and the last few passes you expect. Add a temporary println of the variables the condition reads. If the printed values never approach the limit, or step over it, you have found the cause.

    Key takeaways

    • An infinite loop is a loop whose condition never becomes false.
    • The loop body must change something the condition reads, and change it toward making the condition false.
    • Prefer range conditions (>, <, >=, <=) over exact matches (!=, ==) so a step that skips a value cannot hang the loop.
    • Here, counter != 0 became counter > 0, and the loop now ends after printing 1.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free