问题
Struct A
{
uint16_t len;
uint8_t cnt;
uint8_t unit;
uint32_t seq;
};
This struct A is serialized into a char *
buf. If I want to deserialize the individual values eg:
uint16_t len = 0;
memcpy(&len, buf, sizeof(len));
or I can just do
uint16_t len = (uint16_t) buf;
Which one is better or are both the same?
Also to deserialize the whole struct, if I just do
A tmp;
memcpy(&tmp, buf, sizeof(A));
Would this work fine or should I be worried about padding etc from the compiler?
回答1:
When the data is copied into char[]
buffer, it may not be properly aligned in memory for access as multi-byte types. Copying the data back into struct
restores proper alignment.
If I want to deserialize the individual values eg:
uint16_t len = 0; memcpy(&len, buf, sizeof(len));
Assuming that you have copied the struct
into buf
, this is perfectly valid, because the language guarantees that the initial member would be aligned with the beginning of the structure. However, casting buf
to uint16_t*
is invalid, because the buffer many not be properly aligned in memory to be addressed as uint16_t
.
Note that getting elements of the struct other than the initial one require computing proper offset:
uint32_t seq;
memcpy(&seq, buf+offsetof(struct A, seq), sizeof(seq));
Also to deserialize the whole struct, if I just do
A tmp; memcpy(&tmp, buf, sizeof(A));
Would this work fine or should I be worried about padding etc from the compiler?
This would work fine. Any padding embedded in the struct
when you copied it into the buf
would come back into tmp
, along with the actual data.
来源:https://stackoverflow.com/questions/48571295/difference-between-memcpy-and-copy-by-assignment