0

Can someone please explain me what is the difference between the two following declarations:

char (*arr_a)[5];
char arr_b[20];

and why:

sizeof (*arr_b) = sizeof (char)
sizeof (*arr_a) = 5*sizeof(char)
Yaron Scherf
  • 105
  • 4
  • [C pointer to array/array of pointers disambiguation - Stack Overflow](https://stackoverflow.com/questions/859634/c-pointer-to-array-array-of-pointers-disambiguation) seems related. (Didn't seem duplicate for me) – MikeCAT Aug 15 '17 at 13:46
  • Thinking about writing an *arrays and pointers definitive guide* or something like that. –  Aug 15 '17 at 13:51
  • @Yaron Scherf `=` != `==` – 0___________ Aug 15 '17 at 13:56
  • I'll just note that `sizeof(char)` is, essentially by definition, [always 1](http://en.cppreference.com/w/c/language/sizeof#Notes). – Fred Larson Aug 15 '17 at 13:59

2 Answers2

4
char (*arr_a)[5];

declares a pointer to a 5-element array of char.

char arr_b[20];

declares just a 20-element array of char.

So, the output of

sizeof (*arr_a)

should be straight forward -- dereferencing the pointer to an array yields the array and it's size is 5.

The following:

sizeof (*arr_b)

gives 1, because dereferencing the identifier of an array yields the first element of that array, which is of type char.


One thing you need to know to fully understand this is how an array evaluates in an expression:

  • In most contexts, the array evaluates to a pointer to its first element. This is for example the case when you apply indexing to the array. a[i] is just synonymous to *(a+i). As the array evaluates to a pointer, this works as expected.

  • There are exceptions, notably sizeof, which gives you the storage size of the array itself. Also, _Alignof and & don't treat the array as a pointer.

  • so *arr_a isn't just a pointer (of size sizeof(void*)) but a pointer to an array and therefore it's size is the size of the array? why isn't sizeof(*arr_a) == sizeof(arr_b)? – Yaron Scherf Aug 15 '17 at 13:56
  • `arr_a` is a pointer. `void` doesn't have a size, but `void *` has (as it's a pointer as well). `arr_b` isn't a pointer but an array. You never tried to get the size of `arr_a`, only the size of `*arr_a` (and `*arr_a` is the array `arr_a` points to) –  Aug 15 '17 at 13:57
  • so what would i need to write in order to get size: sizeof(XX)==20*sizeof(char) using arr_b? – Yaron Scherf Aug 15 '17 at 13:59
  • @FelixPalmen He actually wrote `*arr_a` in the comment. It wasn't escaped properly so it shows as italics. – dbush Aug 15 '17 at 13:59
  • @dbush I see. Well that's why you can edit comments as well ;) –  Aug 15 '17 at 14:00
  • @YaronScherf that would be the size of the array, so it's just `sizeof arr_b`. Btw. multiplying by `sizeof(char)` is multiplying by `1`. The size of a `char` is **defined** to be `1`. –  Aug 15 '17 at 14:01
2

arr_a is a pointer to an array of 5 char while arr_b is an array of 20 chars. arr_b is not a pointer unlike arr_a.

sizeof (*arr_b) equals to sizeof (char) because *arr_b is of type char (equivalent to arr_b[0]). For

sizeof (*arr_a) equals to 5*sizeof(char) because *arr_a refers to an array of 5 chars and sizeof returns the size of array which is 5.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • but why do their sizes are different? I would expect that the size of *arr_a will be either size of pointer (sizeof(void*)) or the size of char (like *arr_b) – Yaron Scherf Aug 15 '17 at 13:51
  • @YaronScherf; You are not calculating the size of `arr_a`, but `*arr_a`. – haccks Aug 15 '17 at 13:53
  • @haccks He actually wrote `*arr_a` in the comment. It wasn't escaped properly so it shows as italics. – dbush Aug 15 '17 at 14:00
  • @dbush; OK. I didn't get that. But still answer is valid. – haccks Aug 15 '17 at 14:03