0
int arr[]= {5,15,1,3,4};

    // Since we know arr and &arr are both address of first element of array.
    // I read somewhere that &arr+1 = baseaddress + sizeof(arr).
    // arr+1 = address of second element
    // am curious to know the diff. between two semantics.
printf("%d %d\n",*(arr+1), *(&arr+1));

I know it's trivial, but am curious to clear the concept.

neham
  • 341
  • 5
  • 18
  • 1
    Read [Inconsistency in using pointer to an array and address of an array directly](http://stackoverflow.com/questions/17661078/inconsistency-in-using-pointer-to-an-array-and-address-of-an-array-directly/17663091#17663091) – Grijesh Chauhan Oct 20 '13 at 07:52
  • `*(&arr+1)` undefined behavior, I explained. And you can to read [What does `sizeof(&array)` return?](http://stackoverflow.com/questions/15177420/what-does-sizeofarray-return/15177499#15177499) to understand difference between `(arr+1)`, and `(&arr+1)` – Grijesh Chauhan Oct 20 '13 at 07:53
  • @GrijeshChauhan: +1 It's a dupe – legends2k Oct 20 '13 at 08:28
  • @neham Read updated answer I linked, I added some more information. – Grijesh Chauhan Oct 20 '13 at 18:38

4 Answers4

2

arr is of type array and &arr is of type pointer (array). Their types are not the same.

This &arr+1 is pointer arithmetic. Increasing the &arr by 1 will take you to last position + 1 in the array. Example:

   |0|1|2|3|4| |
 arr^         ^
        &arr+1^
Sadique
  • 22,572
  • 7
  • 65
  • 91
2

The type of arr is int[4] that decays into address of first element in expression arr + 1, adding one results points to second element in arr; whereas type of &arr is int(*)[4] and adding one to &arr make it points to next array that is actually not exist hence dereferences *(&arr+1) undefined behavior at runtime. Consider diagram below:

              +---------------+
              |       5       | --+   arr[0]
              |---------------|   |
 arr + 1 ---> |       15      |   |   arr[1]
              +---------------+   |
              |       1       |   |   arr[2]
              +---------------+   |
              |       3       |   |   arr[3]
              +---------------+   |
              |       4       | --+   arr[4]
              +---------------+
              |   Random      |
&arr + 1 ---->|   Memory      |
              +---------------+
              |               |
              +---------------+

*(arr+1) dereferences the second element of arr and *(&arr+1) dereferences random memory

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
sukhvir
  • 5,265
  • 6
  • 41
  • 43
  • Add this before diagram: "Type of `arr` is `int[4]` that decays into first elements's address and hence `arr + 1` points to second element, whereas type of `&arr` is `int(*)[4]`. and adding one to `&arr` make it points to next array that is actually not exist hence `*(&arr+1)` dereferences - undefined behaviour" – Grijesh Chauhan Oct 20 '13 at 12:01
1

arr is array not the address of first element. It decays to pointer to first element of the array arr. &arr is address of the entire memory block containing the array arr.
In

printf("%d %d\n",*(arr+1), *(&arr+1));

*(arr+1) dereference the second element of array arr (you would get 15 but undefined behavior is invoked so nothing can be said here) while *(&arr+1) will invoke undefined behavior. This is because you are dereferencing an entire block of array past the array arr (out side the allocated memory).

haccks
  • 104,019
  • 25
  • 176
  • 264
1
#include <stdio.h>

int main() {
  int arr[5] = {5,15,1,3,4}; //arr is an array of 5 ints

  //arrays are just pointers to their first value
  printf("the value of arr: %p\n", arr); 
  //this should be the same as arr, since arr is just a pointer to its first value
  printf("the locate of arr[0]: %p\n", &arr[0]);

  //arr+1 is just pointer arithmetic. So arr+1 should be a pointer to the second element in arr.
  printf("When we dereference the pointer to the second element in arr, we should get that number: %d\n", *(arr+1));

  //Since arr is a pointer to the first element in an array, address-of'ing it gives us the address of that pointer in memory.
  printf("*(&arr+1): %p\n", *(&arr+1));
  //Adding 1 to the address of a pointer just gives us a higher address that points to nothing in particular (some place on the stack)
}

/*
 * Output:
 * the value of arr: 0x7ffff2681820
 * the locate of arr[0]: 0x7ffff2681820
 * When we dereference the pointer to the second element in arr, we should get that number: 15
 * *(&arr+1): 0x7ffff2681834
 */

Edit: By adding prints for the other 4 memory addresses we can see that *(&addr+1) points to the location right after the fifth element in the array.

 arr+1: 0x7fff38560224

 arr+2: 0x7fff38560228

 arr+3: 0x7fff3856022c

 arr+4: 0x7fff38560230
numberten
  • 136
  • 1
  • 3