我有以下两种结构。我需要从d, e, f
复制source
到destination
使用memcpy
and offsetof
。我怎样才能做到这一点?
struct source
{
int a;
int b;
int c;
int d;
int e;
int f;
};
struct destination
{
int d;
int e;
int f;
};
通常,您不能使用 可靠地做到这一点memcpy
,因为允许编译器以不同的方式填充这两个结构。因此,执行部分复制的最安全方法是分别分配三个字段。
但是,由于编译器仅在具有不同对齐要求的成员之间插入填充,因此在您的特定情况下,您可以memcpy
像这样使用:
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));
destination
's的偏移量d
保证为零,因为它是结构的初始成员。由于成员d
、e
和f
具有相同的对齐要求,因此填充(如果有)将在 中位于它们之后,在struct destination
中位于它们之前或之后struct source
。
强制转换为char*
是必需的,因为偏移量以字节表示。
表达方式
offsetof(struct source,f)-offsetof(struct source,d)+sizeof(int)
d
是和之间的运行长度f
,包括在内。请注意, usingsizeof(struct destination)
是不安全的,因为它可能在末尾有填充,而不存在于 中struct source
,从而导致读取分配的内存。
memcpy
正如“dasblinkenlight”所说,由于可能的填充,这不能可靠地完成。但是,您可以执行以下操作:
struct Part1
{
int a;
int b;
int c;
};
struct Part2
{
int d;
int e;
int f;
};
struct source
{
struct Part1 p1;
struct Part2 p2;
};
struct destination
{
struct Part2 p2;
};
// ...
src.p2 = dst.p2;
对于这种情况,您还可以使用指向源和目标结构的 int 指针,然后在目标指针中分配值并减少源和目标 int 指针。
代码片段如下:-
struct destination * my_copy (struct source *pfSrc, struct destination *pfDes)
{
int *pSrc = (int *)pfSrc;
int *pDes = (int *)pfDes;
pSrc += (sizeof (struct source)/sizeof (int)) - 1;
pDes += (sizeof (struct destination)/sizeof (int)) - 1;
do
{
*pDes = *pSrc;
pSrc--;
}while (pDes-- != (int *)pfDes);
return pfDes;
}