9

Here I have a pointer ptr to array arr of 4 integers. ptr points to the whole array. ptr[0] or *ptr points to the first element of the array, so adding 1 to ptr[0] gives the address of the second element of the array.

I can't understand why using sizeof(ptr[0]) gives the size of the whole array, 16 bytes, not the size of only the first element, 4 bytes, (as ptr[0] points to the first element in the array).

int arr[4] = {0, 1, 2, 3};
int (*ptr)[4] = &arr;
printf("%zd", sizeof(ptr[0])); //output is 16
AbdelAziz AbdelLatef
  • 3,650
  • 6
  • 24
  • 52
  • Shouldn't the second line be `int *ptr = arr;` ? That would make it point to the start (first element of) the array, which is equivalent to `&arr[0]`. – Andreas Wenzel Oct 27 '19 at 16:48
  • 1
    @AndreasWenzel *Shouldn't the second line be `int *ptr = arr;`?* Actually, no. `int (*ptr)[4]` creates `ptr` as a pointer to a full array of four `int` values. Pointer syntax like that is necessary to dynamically allocate true-multidimensional arrays. The "2-dimensional arrays" created with nested `malloc()` loops and wrongly described as multidimensional arrays are really 1-d arrays of pointers to multiple 1-d arrays. See https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays – Andrew Henle Oct 27 '19 at 17:02

4 Answers4

6

OP: ptr[0] points to the first element in the array.

Type confusion. ptr[0] is an array.

ptr is a pointer to array 4 of int.
ptr[0], like *ptr deferences the pointer to an array.
sizeof(ptr[0]) is the size of an array.


With sizeof(ptr[0]), ptr[0] does not incur "an expression with type ‘‘pointer to type’’ that points to the initial element of the array object" conversion. (c11dr §6.3.2.1 3). With sizeof, ptr[0] is an array.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
5

ptr here is of type pointer to an array of 4 int elements and the array type has size 16 on your platform (sizeof(int) * (number of elemetns)).

I can't understand why using sizeof(ptr[0]) gives the size of the whole array 16 bytes not the size of only the first element 4 bytes

because C type system has array types. Here both arr and *ptr has it. What you declare that you have. To get sizeof int here you should sizeof(ptr[0][0]) - where ptr[0] evaluates to array.

Volodymyr Boiko
  • 1,533
  • 15
  • 29
2

with int (*ptr)[4] = &arr ; you have a pointer to an array of four integers and pointing to arr.

ptr is now pointing to arr, like a double pointer. We can access elements of arr using ptr[0][x] where x could be 0 to 4.

So sizeof(ptr[0]) is same as sizeof(arr)

rsonx
  • 436
  • 7
  • 16
2

By definition, ptr[0] is the same as *(ptr + 0) which in turn is the same as *ptr. Further, ptr is initialized with &arr, so *ptr is *&arr and that is just arr. Note that the intermediate storage of &arr in ptr does not perform any array decay, so the equivalence is maintained and no type information is lost.

Note that all this is computed at compile-time, just to avoid this additional pitfall.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55