Why Does This Go into an Infinite Loop

Why does this go into an infinite loop?

Note: Originally I posted C# code in this answer for purposes of illustration, since C# allows you to pass int parameters by reference with the ref keyword. I've decided to update it with actual legal Java code using the first MutableInt class I found on Google to sort of approximate what ref does in C#. I can't really tell if that helps or hurts the answer. I will say that I personally haven't done all that much Java development; so for all I know there could be much more idiomatic ways to illustrate this point.


Perhaps if we write out a method to do the equivalent of what x++ does it will make this clearer.

public MutableInt postIncrement(MutableInt x) {
int valueBeforeIncrement = x.intValue();
x.add(1);
return new MutableInt(valueBeforeIncrement);
}

Right? Increment the value passed and return the original value: that's the definition of the postincrement operator.

Now, let's see how this behavior plays out in your example code:

MutableInt x = new MutableInt();
x = postIncrement(x);

postIncrement(x) does what? Increments x, yes. And then returns what x was before the increment. This return value then gets assigned to x.

So the order of values assigned to x is 0, then 1, then 0.

This might be clearer still if we re-write the above:

MutableInt x = new MutableInt();    // x is 0.
MutableInt temp = postIncrement(x); // Now x is 1, and temp is 0.
x = temp; // Now x is 0 again.

Your fixation on the fact that when you replace x on the left side of the above assignment with y, "you can see that it first increments x, and later attributes it to y" strikes me as confused. It is not x that is being assigned to y; it is the value formerly assigned to x. Really, injecting y makes things no different from the scenario above; we've simply got:

MutableInt x = new MutableInt();    // x is 0.
MutableInt y = new MutableInt(); // y is 0.
MutableInt temp = postIncrement(x); // Now x is 1, and temp is 0.
y = temp; // y is still 0.

So it's clear: x = x++ effectively does not change the value of x. It always causes x to have the values x0, then x0 + 1, and then x0 again.


Update: Incidentally, lest you doubt that x ever gets assigned to 1 "between" the increment operation and the assignment in the example above, I've thrown together a quick demo to illustrate that this intermediate value does indeed "exist," though it will never be "seen" on the executing thread.

The demo calls x = x++; in a loop while a separate thread continuously prints the value of x to the console.

public class Main {
public static volatile int x = 0;

public static void main(String[] args) {
LoopingThread t = new LoopingThread();
System.out.println("Starting background thread...");
t.start();

while (true) {
x = x++;
}
}
}

class LoopingThread extends Thread {
public @Override void run() {
while (true) {
System.out.println(Main.x);
}
}
}

Below is an excerpt of the above program's output. Notice the irregular occurrence of both 1s and 0s.


Starting background thread...
0
0
1
1
0
0
0
0
0
0
0
0
0
0
1
0
1

Why does this method go into an infinite loop?

The problem is

while(count[str[i]-'a']--) { ... }

the reason is the expression

x--

decrements x and returns the original value (before decrementing). Using a while condition like

while(x--) { ... }

quits the loop when x goes from 1 to 0, but if you enter the while again then you've a problem because x made it to -1 and it will not get back to zero by decrementing it.

-1 is a "true value" for a while test, so it will enter the loop and become -2, then loop again and become -3 and so on until you get an overflow and undefined behavior.

The loop should be probably written as

while(count[str[i]-'a']) {
count[str[i]-'a']--;
....
}

so that you decrement it ONLY if it's not already zero

why does this program go into an infinite loop?

C arrays are zero-based so you should use indexes [0..4] rather than [1..5].

Writing to a[5] writes beyond the bounds of your array. This has undefined results; in your case, this happens to be the address of your loop counter i which is reset to 0.

You can fix this by using

for (i = 0; i < 5; i++)

or, better,

for (i = 0; i < sizeof(a)/sizeof(a[0]); i++)

as your loop.

Why does this while loop cause an infinite loop?

The problem is your condition - because even if you reach 1, the loop will continue.
Replace while (input >= 1) with while (input > 1)

Why do i get an infinite loop when I use int instead of Integer in Java?

Don't use == to compare Integers. It only works when you pre-box temp because of reference equality. Use .equals() instead:

if (queue.peek().equals(maxDeque.peekFirst())) {
maxDeque.pollFirst();
}

if (queue.peek().equals(minDeque.peekFirst())) {
minDeque.pollFirst();
}


Related Topics



Leave a reply



Submit