I have the following two structures. I need to copy d, e, f
from source
to destination
using memcpy
and offsetof
. How can I do this?
struct source
{
int a;
int b;
int c;
int d;
int e;
int f;
};
struct destination
{
int d;
int e;
int f;
};
Generally, You cannot reliably do it using memcpy
, because the compiler is allowed to pad the two structures differently. So the safest way of performing a partial copy would be to assign the three fields individually.
However, since the compiler inserts padding only between members with different alignment requirements, in your specific case you can use memcpy
like this:
struct source s {1,2,3,4,5,6};
struct destination d = {100, 200, 300};
memcpy(&d, ((char*)(&s))+offsetof(struct source,d), offsetof(struct source,f)-offsetof(struct source,d)+sizeof(int));
The offset of destination
's d
is guaranteed to be zero because it is the initial member of the structure. Since members d
, e
, and f
have identical alignment requirements, the padding, if any, will go after them in the struct destination
, and before or after them in the struct source
.
Cast to char*
is required because the offset is expressed in bytes.
The expression
offsetof(struct source,f)-offsetof(struct source,d)+sizeof(int)
is the length of the run between d
and f
, inclusive. Note that using sizeof(struct destination)
is not safe, because it may have padding at the end which is not present in struct source
, causing a read past the allocated memory.