Interesting ways to get into infinite loops while programming

As the title of the post suggest, we are going to see how naive and careless programming mistakes can sometime lead us to infinite loops. But first thing first, we need to understand what an infinite loop is. In programming, an infinite loop occurs when the intend set of repeatable programmable statements execute indefinitely unless terminated by manual/system intervention like sending a system signal to the program which the program cannot handle. Why is an infinite loop bad? Well, one the infinite loop does not do much other than doing the same set of operations again and again and two it hogs or wastes the system resources like memory and CPU processing time thereby affecting the running behavior of other programs and threads serviced by the operating system. Consider the following code snippet:-

1: i = 0;
2: while (i < 10) {
3: char* ch = (char*)malloc(1000);
4: printf("%d\n", i);
6: }
5: continue;

Clearly, we are not incrementing variable 'i' in the while loop, which means that this loop will execute forever. Not that the loop does not do nay useful work and is leaking a lot of memory by allocating 1000 bytes of memory in every iteration. Petty soon, other applications will slow down due too much memory allocations done by this faulty infinite loop and the operating system having to swap in and swap out the requested pages from the disk to physical memory (virtual memory).

Is the infinite loop always bad for the system? Sometime the infinite loops are internationally created in the program to perform some specific functions forever. Such programs which do some meaningful work forever are sometime referred to as daemons. The infinite loops in the daemons are carefully designed to do some specific work only in certain situations. Like for instance, sshd daemon on Linux operating system is running forever but takes actions only when certain ssh session request is received on the operating system.

In this blog post we will look at some programmatic mistakes which can lead to infinite loops. As most programmers may have experienced, debugging an infinite loop is never easy. For avoiding running into 'infinite' loops or debugging them, we need to know the semantics of the programming language very well. Below are some examples which can help avoiding getting into infinite loop or debugging them.

1. Know the loop structure.
Let's begin by looking at a simple comparison between two loops. Please consider the following code snippets. Which of the 'for' and 'while' loops will loop forever? Will both of them will loop forever?

1: int i;
2: for (i =0; i < 10; ++i) {
3: printf("%d\n", i);
6:
4: continue; 5: }
9: printf("%d\n", i)
7: int i = 0; 8: while (i < 10) {
12: }
10: continue;
11: ++i;

As many of you may have guessed correctly, the 'while' loop runs forever while the 'for' loop terminates as the variable 'i' reaches value 10. What is the difference between the two loops? We are calling 'continue' at nearly the same time after calling the function 'printf()' to print the value of variable 'i' on the console. On closer examination of the 'while' loop we see that, we do not increment 'i' at all before checking the condition 'i < 10' at the beginning of the loop (because of the 'continue'). While in the 'for' loop at the increment operation '++i' happens every time before the comparison 'i < 10' (implementation details of the 'for' loop). Hence the 'continue' statement in the 'for' loop is redundant.

What if we remove the statement '++i' in the header of the 'for' loop and place it after the 'continue' statement in the 'for' loop as in the code snippet below? Will the 'for' loop run infinite times now?

1: int i;
2: for (i =0; i < 10;) {
3: printf("%d\n", i);
5: ++i;
4: continue;
6: }

Turns out, that the loop will not terminate now. We have now bypassed the increment operation '++i' by the 'continue' statement and there is no increment operation on 'i' in the header of the 'for' loop.

2. Know your operators
Could the following loop snippet run infinite times?

1: int i;
2: for (i =0; i < 10; +i) {
3: printf("%d\n", i);
5: }
4: continue;
Yes, the above loop snippet will run infinitely. Well, the snippet looks some what similar to the 'for' loop in the section "Know the loop structure" which terminated in finite time. However, closer examination of the intended increment operation '+i' in the 'for' loop header will reveal that the statement '+i' is not an increment operation. The statement "+i" returns the value the current value of 'i' but does not increment the value of 'i' by one. The '+i' operation compiles fine without any errors in 'gcc' compiler.The output of the following code snippet is '100'.

1: i = 100;
2: printf("%d\n", +i);

In fact '+i' returns the value of 'i', '-i' is also a valid operation and returns the negative value of 'i'. Consider the following code snippet and outputs:-

1: i = 100;
2: printf("%d\n", +i); // Output 100
3: printf("%d\n", -i); // Output -100
4: printf("%d\n", -(-i)); // Output 100

Interestingly, operation '*i', '/i' and '%i' are illegal operations in C programming and do not compile.



Comments

Popular Posts