1

我有以下两种结构。我需要从d, e, f复制sourcedestination使用memcpyand offsetof。我怎样才能做到这一点?

struct source
{
    int a;
    int b;
    int c;
    int d;
    int e;
    int f;
};

struct destination
{
    int d;
    int e;
    int f;
};
4

3 回答 3

5

通常,您不能使用 可靠地做到这一点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保证为零,因为它是结构的初始成员。由于成员def具有相同的对齐要求,因此填充(如果有)将在 中位于它们之后,在struct destination中位于它们之前或之后struct source

强制转换为char*是必需的,因为偏移量以字节表示。

表达方式

offsetof(struct source,f)-offsetof(struct source,d)+sizeof(int)

d是和之间的运行长度f,包括在内。请注意, usingsizeof(struct destination)是不安全的,因为它可能在末尾有填充,而不存在于 中struct source,从而导致读取分配的内存。

于 2012-05-10T12:47:14.103 回答
1

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;
于 2012-05-10T12:54:11.827 回答
0

对于这种情况,您还可以使用指向源和目标结构的 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;
}
于 2012-05-10T13:52:51.483 回答