Why does this for loop exit on some platforms and not on others?
Solution 1:
On my laptop running Ubuntu 14.04, this code does not break it runs to completion. On my school's computer running CentOS 6.6, it also runs fine. On Windows 8.1, the loop never terminates.
What is more strange is when I edit the conditional of the
for
loop to:i <= 11
, the code only terminates on my laptop running Ubuntu. CentOS and Windows never terminates.
You've just discovered memory stomping. You can read more about it here: What is a “memory stomp”?
When you allocate int array[10],i;
, those variables go into memory (specifically, they're allocated on the stack, which is a block of memory associated with the function). array[]
and i
are probably adjacent to each other in memory. It seems that on Windows 8.1, i
is located at array[10]
. On CentOS, i
is located at array[11]
. And on Ubuntu, it's in neither spot (maybe it's at array[-1]
?).
Try adding these debugging statements to your code. You should notice that on iteration 10 or 11, array[i]
points at i
.
#include <stdio.h>
int main()
{
int array[10],i;
printf ("array: %p, &i: %p\n", array, &i);
printf ("i is offset %d from array\n", &i - array);
for (i = 0; i <=11 ; i++)
{
printf ("%d: Writing 0 to address %p\n", i, &array[i]);
array[i]=0; /*code should never terminate*/
}
return 0;
}
Solution 2:
The bug lies between these pieces of code:
int array[10],i;
for (i = 0; i <=10 ; i++)
array[i]=0;
Since array
only has 10 elements, in the last iteration array[10] = 0;
is a buffer overflow. Buffer overflows are UNDEFINED BEHAVIOR, which means they might format your hard drive or cause demons to fly out of your nose.
It is fairly common for all stack variables to be laid out adjacent to each other. If i
is located where array[10]
writes to, then the UB will reset i
to 0
, thus leading to the unterminated loop.
To fix, change the loop condition to i < 10
.