Why does * need to be put before (&a) to subtract a (a is an array)?
The memory address of the array is the same as the memory address of the first element, and when you add to or subtract from a pointer, it is done by the size of the type it points to, so:
arr
refers toint
, and&arr
refers toint[5]
.&arr+1
increments the memory address in the size of five integers.- If you do
(&arr+1)-arr
you get a compile error, because they are different types. - If you do
(&arr+1)-&arr
you get1
, because the offset of the memory address is the same as one size ofint[5]
. - Therefore, when you do
*(&arr+1)
, you get the same memory address but pointing toint
and notint[5]
. Now you wont get a compile error, because both pointers point toint
and you get the offset of the memory address in terms ofint
size, and notint[5]
. Memory addresses and types are quite difficult to explain sometimes, I hope I made it clear. Here you have some code you can run to see some of the concepts mentioned:
int arr[5] = {5, 8, 1, 3, 6};
int len = *(&arr + 1) - arr;
cout << "arr: " << arr << endl;
cout << "arr + 1: " << arr+1 << endl;
cout << "&arr: " << &arr << endl;
cout << "&arr + 1: " << &arr+1 << endl;
cout << "*(&arr + 1): " << *(&arr+1) << endl;
// cout << "&arr + 1 - arr: " << &arr+1-arr << endl;
// error: invalid operands of types ‘int (*)[5]’ and ‘int [5]’ to binary ‘operator-’
cout << "The length of the array is: " << len;
The type of the array arr
is int[5]
, the type of &arr
is int(*)[5]
. (&arr + 1)
increases the array address on sizeof(int[5])
as it's done by the rules of the pointer arithmetic, i.e. computes the address after the array. *(&arr + 1)
is int[5]
, an array right after arr
, where arr[5]
would place. The both arguments of the substractions decay to int*
. The substraction of pointers to int gives 5.
This may be considered as undefined behavior, since substraction of pointers belonging to different object storages is not defined. Also results of expressions with pointers addressing unallocated memory (like the (&arr + 1)
) are undefined.