Say I have the following code:
char buff[100] = {0};
char msg[] = "hello!";
memcpy(buff, msg, sizeof(msg));
OR
memcpy(&buff, msg, sizeof(msg));
Why do the two memcpy lines work exactly the same?
I expected that when &buff is used, it would copy the msg into the memory where the pointer itself that buff decays into is stored, not the memory that that pointer actually points to.
When I imagine the pointers like this:
&buff->buff->buff[0]
I can rationalize why they behave the same. But when I imagine the actual memory like this:
address | value | (name)
-------------- --------- ----------------
0x1000 | 'h' | (buff[0])
0x1001 | 'e' | (buff[1])
... etc
__________________________________________
0x5000-0x5008 | 0x1000 | (buf - char *)
__________________________________________
0x8000-0x8008 | 0x5000 | (&buf - char**)
__________________________________________
Now I cannot see why the msg is not written at address 0x5000 instead, overwriting the value 0x1000.
C 2018 6.3.2.1 3 says an array is converted to a pointer to its first element except when:
sizeof,&, orSo, in
memcpy(&buff, msg, sizeof(msg)),buffis the operand of unary&and is not converted to a pointer.&buffgives a pointer to the array.In
memcpy(buff, msg, sizeof(msg)),buffis converted to a pointer to its first element.The starting location of the first element and the starting location of the array are the same location. So
&buffandbuffhave the same value, but different types. So data is copied to the same place in both calls.(Also note that the difference in types becomes irrelevant because the first parameter of
memcpyis declared to bevoid * restrict, so both&buffandbuffare converted to the same type before the call.)