开发者

Mystery regarding for-loop

I am stuck with this mystery regarding for loop.

    int abc[3], i, j;
    for(j=0; j<3; j++);
    printf("%d\n", j);
    abc[j] = abc[j] + 3;
    printf("%d \n", j开发者_运维技巧);


Output: 

3
6 

Output should have been 3,3 as I've not changed value of j.

Adding 3 to the jth value of abc has resulted in change of value of j by 3. This happens only while exiting from a for loop and then trying to change the value of abc[j].

Maybe I am missing something pretty obvious. Any help would be much appreciated.


You have a buffer overflow since you declared your array to have size 3 int abc[3]; yet you are indexing the 4th element; this is Undefined Behavior.

abc[j] = abc[j] + 3; // j = 3 here, overflow

What you are most likely seeing is that j is located on the stack just past your array abc and so when you overflow one past the array with abc[3], you're actually modifying the memory that contains j.

*Note that nowhere in the C standard does it mention the word stack, this is an implementation detail and can change from system to system. This is partly the reason why it is Undefined Behavior and you are getting responses from people that they see two 3's as output.


You're indexing past the end of the array (buffer overflow) and reassigning other variables on the stack.

int abc[3], i, j;
// Your stack looks like this (single 'x' is one byte):
// |abc[0]|abc[1]| abc[2]| j  |  i |
// 
// |xxxx  |xxxx  |xxxx   |xxxx|xxxx|
// 
for(j=0; j<3; j++);
printf("%d\n", j);
// j = 3 at this point
// abc[3] points past the end of the array abc, in this case, at j.
// So the next statement increments j by 3.
abc[j] = abc[j] + 3;
printf("%d \n", j);

To verify, try adding the following statements at the end:

printf("%d\n", &i == &abc[3]);
printf("%d\n", &j == &abc[3]);

EDIT

The exact layout of the stack will matter depending on the compiler you're using:

misha@misha-desktop:~/Desktop/stackoverflow$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
misha@misha-desktop:~/Desktop/stackoverflow$ ./a.out
3
3

Here's why it's working fine on my machine -- the statement:

printf("abc: %x abc[3]: %x i: %x j: %x\n", &abc, &abc[3], &i, &j);

gives the following output:

abc: 4cd0aa70 abc[3]: 4cd0aa7c i: 4cd0aa8c j: 4cd0aa88

So the stack is actually:

//  aa70   aa74     aa78   aa7c            aa88  aa8c
// |abc[0]|abc[1]| abc[2]|      |  ....  |  j  |  i  |

So when it's accessing abc[3], it's accessing 0x4cd0aa7c which is just "dead space".


When J = 3, abc[j] refers to 4th element, since, array indexes begin with 0 and not 1. So, you are trying to access a location which is beyond the memory area of the array abc. Coincidentally this location happens to be that of J. Hence, value of J gets modified. Try changing the order of declaration of variables to better understand this behavior.

Thanks,
Vamyip


for(j=0; j<3; j++);

You have a semicolon at the end of the for loop. Problem solved.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜