Primal Pappachan
Primal Pappachan

Reputation: 26535

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.

Upvotes: 1

Views: 222

Answers (4)

Lundin
Lundin

Reputation: 214810

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

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

Upvotes: 0

mpenkov
mpenkov

Reputation: 21912

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".

Upvotes: 5

SiegeX
SiegeX

Reputation: 140467

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.

Upvotes: 14

vamyip
vamyip

Reputation: 1171

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

Upvotes: 1

Related Questions