Reputation: 13
int main() {
uint32_t x;
uint32_t* p = (uint32_t*)malloc(sizeof(uint32_t));
uint32_t array[9] = {42, 5, 23, 82, 127, 21, 324, 3, 8};
*p = *(uint32_t*) ((char*) array + 8);
printf("l: %d\n", *p);
return 0;
}
Why does *p
print the value of the second index of array
after *p = *(uint32_t*) ((char*) array + 8);
?
Upvotes: 1
Views: 63
Reputation: 181849
Perhaps the question revolves around operator precedence and associativity. This expression ...
*(uint32_t*) ((char*) array + 8)
... is equivalent to ...
*((uint32_t*) (((char*) array) + 8))
... NOT ...
*((uint32_t*) ((char*) (array + 8))) // not equivalent
Typecast operators have very high precedence, higher than binary +
, in particular. Pointer arithmetic works in units of the pointed-to type, and the type of ((char *) array)
is, or course, char *
. Its pointed to type is char
. Therefore, (((char*) array) + 8)
evaluates to a pointer to the 8th char past the beginning of the array.
Your implementation has 8-bit char
s, which is exceedingly common (but not universal). Type uint32_t
has exactly 32 bits, and so comprises four 8-bit char
s. It follows that (((char*) array) + 8)
points to the first char
of the third uint32_t
in array
, as the 8 bytes skipped are exactly the bytes of the first two uint32_t
s.
When that pointer is converted back to type uint32_t *
, it points to the whole third uint32_t
of the array, and the value of that element, 23, is read back by dereferencing the pointer with the unary *
operator.
Upvotes: 3
Reputation: 68059
sizeof(uint32_t)
is 4
sizeof(char)
is 1
=> 8 * sizeof(char) == 8
8 / sizeof(uint32_t) = 2
then ((char *)array) + 8 == array + (8 / sizeof(uint32_t))
p = array + (8 / sizeof(uint32_t))
=> p = array + 2
then *p == array[2] == 23
Upvotes: 2