Ronny Roy
Ronny Roy

Reputation: 13

Pointer Arithmetic - Issues with array and pointer to an array

I've switched to C recently and was trying to figure out pointers.

#include <stdio.h>

int main()
{
    int arr[5] = {1,2,3,4,5};
    int *a = &arr;

    printf("Array : %p\n", arr);
    for(int i=0; i<5; i++)
    {
        printf("Value and Address of Element - %d : %d\t%p,\n", i+1, arr[i], &arr[i]);
    }
    printf("Pointer to the Array : %p\n", a);
    printf("Value pointed by the pointer : %d\n", *a);
    a = (&a+1);
    printf("Pointer after incrementing : %p\n", a);
    return 0;
}

However, the following line doesn't seem to work.

a = (&a+1);

After printing the incremented value of the pointer a, it still points to the array (arr). Here's the output of the program:

Array : 0x7ffe74e5d390
Value and Address of Element - 1 : 1    0x7ffe74e5d390,
Value and Address of Element - 2 : 2    0x7ffe74e5d394,
Value and Address of Element - 3 : 3    0x7ffe74e5d398,
Value and Address of Element - 4 : 4    0x7ffe74e5d39c,
Value and Address of Element - 5 : 5    0x7ffe74e5d3a0,
Pointer to the Array : 0x7ffe74e5d390
Value pointed by the pointer : 1
Pointer after incrementing : 0x7ffe74e5d390

As you can see the pointer 'a' still points to the first element. However, in theory shouldn't 'a' point to whatever's after the last element (Given that &a + 1 increments the pointer by the size of the entire array - source: difference between a+1 and &a+1)

Could someone explain why?

Upvotes: 0

Views: 364

Answers (2)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38415

In this particular case the variable and the array may be placed on the stack like below, that is not guaranteed by the standard. Each cell is int. Do you remember the stack address is reduced on each local var placed.

+-+-+-+-+-+-+
|a|1|2|3|4|5|
+-+-+-+-+-+-+

&a+1, it is not the address of the array, you take the address of a, move on one cell and get the address of the array as a result.

Upvotes: 0

Eric Postpischil
Eric Postpischil

Reputation: 222437

a = (&a+1); sets a to point to one “thing” beyond the address of a.

Earlier, your code sets a to &arr, using int *a = &arr;. (This violates standard C constraints because the type of &arr is a pointer to an array, not a pointer to an int. The correct definition would be int *a = arr;.) I suspect your intent in a = (&a+1); was to set a to point to one beyond where it currently points. However, correct code for this would be a = a+1;. That takes the value of a, adds one to it, and assigns the result to a. In contrast, a = (&a+1); uses the address of a instead of its value.

This results in a pointing to one beyond wherever a is in memory. In your experiment, it seems that the array arr happened to be there, and your C implementation behaved accordingly.

(That explains the results you observed, but it is not behavior you should rely on. The C standard does not define what happens when you misuses pointers in this way, and various things, including compiler optimization, can cause programs to behave as if &a+1 did not point to arr even if arr is in fact located at the address &a+1 in memory.)

Upvotes: 1

Related Questions