1

I'm playing around with pointers in C, and I can't seem to understand the results I'm getting.

Look at the last iteration & the print statement after the loop, why do I get different values inside and outside the for-loop?

#include <stdio.h>

int main(void)
{
    int *ptr;
    int a1[] = {2, 5, 4, -1};
    ptr = &a1[0];

    for (int i = 0; i < 4; i++)
    {
        printf("######## ITERATION %d ########\n", i);
        printf("a1[%d] = %d. \n", i, a1[i]);
        printf("Current location - %ld \n", ptr);
        ptr = ptr + 1;
        printf("Next value would be - a1[%d] = %d at location - %ld\n\n\n", i+1, *ptr, ptr);
    }
    printf("%ld - %d\n", ptr, *(ptr));
}

And this would be the output -

*** ITERATION 0 ***
a1[0] = 2.
Current location - 2686728
Next value would be - a1[1] = 5 at location - 2686732

*** ITERATION 1 ***
a1[1] = 5.
Current location - 2686732
Next value would be - a1[2] = 4 at location - 2686736

*** ITERATION 2 ***
a1[2] = 4.
Current location - 2686736
Next value would be - a1[3] = -1 at location - 2686740

*** ITERATION 3 ***
a1[3] = -1.
Current location - 2686740
Next value would be - a1[4] = 3 at location - 2686744

2686744 - 4

Look at what I get from the last iteration - The location is 2686744 and the value is 3, and once I make the same print OUTSIDE the for-loop, it has the value 4, for the same address...

This leads to 2 questions -

  1. Where does that value even come from? There clearly isn't anything after 2686740. That's where the array ends...
  2. Why does 2686744 have a different value when I print it inside the loop, and outside?

Thanks in advance!

thomas
  • 1,133
  • 1
  • 12
  • 31
  • Your program has undefined behaviour, since `%ld` expects a `long int` argument and you provide an `int *` value. – Kerrek SB Nov 18 '14 at 12:25
  • I wonder how you got `*`s in the output... – Spikatrix Nov 18 '14 at 13:00
  • @Cool Guy - lol, I changed the code because it was too heavy on the eye with the '#', and the post seemed too long for me anyway. I must have posted the old code with the new output :) – thomas Nov 18 '14 at 17:24

6 Answers6

8

First of all, use %p to print pointers. Then,you have undefined behaviour in your code as you access the 5th element of the array(a[4]) in the last iteration(after incrementing ptr). This is why you get different values.

Spikatrix
  • 20,225
  • 7
  • 37
  • 83
  • `%p` requires that the pointer be in the form of a `void *`... An example of using it correctly would be icing on the cake, but this gets my +1 :) – autistic Jun 10 '15 at 15:22
  • I know that the standard requires the argument of `%p` to be of type `void*` but I've never seen issues when it is omitted (Even on other systems). Thanks for the +1 ! :-) – Spikatrix Jun 11 '15 at 05:34
  • It may coincidentally work for you at the moment, but according to the C standard, ["If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined."](http://www.iso-9899.info/n1570.html#7.21.6.1p9) – autistic Jun 11 '15 at 06:42
5

Probably you are looking at the memory location where the loop variable i is stored (which value is 3 at that time). Note that you thereby enter the realm of undefined behavior. You are not allowed to access memory beyond the array's boundary.

After the loop ended, the variable (that previously existed) at that very place was incremented one more time. Therefore you've observed a 4. Note that this is, again, undefined behavior. You are not allowed to access memory regions belonging to objects that went out of scope.

In short, anything could have happened. Note that your program is not required to crash, or even warn you, when you are doing something wrong. Not everything that appears to work is indeed valid code. In this sense, I suggest, to also revisit the documentation of the printf() function and try to comprehend the variety of format specifiers there are, especially for pointers and different sized integers.

moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • Everybody said "anything could have happened" - Am I supposed to understand why, or as a beginner should I simply accept this as an axiom? – thomas Nov 18 '14 at 12:32
  • @thomas This post is a very good read in this respect: http://stackoverflow.com/a/6445794/1025391 – moooeeeep Nov 18 '14 at 12:38
1

For each loop, you first print then increase the pointer. So after the final run in the loop, you print the 4th item of the array, then increase the pointer out-of-bounds, pointing at a 5th item which doesn't exist. This is undefined behavior so anything can happen, including garbage values getting printed.

Lundin
  • 195,001
  • 40
  • 254
  • 396
1

Well, first of all, from an array of 4 positions, you are printing the content of a fifth position... That means that value is "trash", it is, there's no meaning in this value at all. Remember, the last position of an array is ALWAYS n-1, where n is the size of the array (it's number of elements), and the first position is 0.

0

Accessing array out of bound. Use %p to print pointers. Your array holds 4 elements so you should not be accessing the a[4], which is array out of bound access. The array index for the array is 0-3. By the time you end the the for loop your pointer will be pointing some memory which is not in array bound so printing its value after completing the loop makes no sense.

Check the below code:

#include <stdio.h>

int main(void)
{
    int *ptr;
    int i;
    int a1[] = {2, 5, 4, -1};
    ptr = &a1[0];

    for ( i = 0; i < 4; i++)
    {
        printf("######## ITERATION %d ########\n", i);
        printf("a1[%d] = %d. \n", i, a1[i]);
        printf("Current location - %p \n", ptr);
        ptr = ptr + 1;
        if(i != 3) 
        printf("Next value would be - a1[%d] = %d at location - %p\n\n\n", i+1, *ptr, ptr);
    }

}
Gopi
  • 19,784
  • 4
  • 24
  • 36
0

Since a[4]is pointing to and addres that does no belong to the array, it cuold be another variable of your program, a variable for another program or rubbish (data used for another program and that is not being used actually). It looks is the value of i, but you can no be suerd, maybe is data belonging to another program that has being actualised between your two last prints.

Narkha
  • 1,197
  • 2
  • 12
  • 30