【问题标题】:Copying structure members复制结构成员
【发布时间】:2014-05-23 11:24:02
【问题描述】:

我对结构更加困惑。复制结构的方法有很多种。

struct complex
{
   int real;
   int imaginary;
};

Assume c1 is complex structure variable. c2 is pointer of complex type.

一种方法是将一个结构简单地分配给另一个结构。 c1=*c2。 我尝试过这个。它工作正常。但是 c2 将给出结构复杂的第一个元素的地址。那么整个结构将如何被复制呢?我对指针更困惑吗?

另一种方法是使用memcpymemcpy(&c1,c2,sizeof(struct complex))

我的疑问在于成员结构复制。 memcpy(&c1.real, &c2->real, sizeof(struct complex))

我读到上述方法并不安全。因为如果我们更改结构成员的顺序,它将不起作用。没人解释怎么不安全?它让我感到困惑,因为这两个变量都是相同的结构,我正在指定我想要复制的内容[在这种情况下是真实的]。那为什么不安全呢?谁能解释一下?

【问题讨论】:

  • memcpy(&c1.real, &c2->real, sizeof(struct complex)) - 你应该看到这是非常有问题的。问题不在于这不安全,这完全是错误的。复制多少以及复制到哪里?它可能会起作用,但它不必以任何方式起作用。我也不明白你真正问的是什么。
  • 在你复制成员明智结构复制的行中......你正在复制成员&c1.real但给出结构的大小......只需给出变量的大小.....然后试试看..!!!
  • 使用 memcpy 对于您正在做的事情是不必要的。只需使用作业。第二个 memcpy 不好,因为您试图复制 sizeof(struct complex) 字节,而它应该是 sizeof(int) 字节。如果你把 real 放在 complex 之后,它将开始写入结构内存的末尾,因为它仍然会写入(大概)8 个字节。您现在所拥有的将复制整个结构,但这是一种晦涩难懂的方式。如果你对除第一个成员之外的任何其他成员执行此操作,memcpy 将在结构之外编写(或至少尝试)一些内容

标签: c struct


【解决方案1】:

当然,唯一理智的方法是使用赋值:

c1 = *c2;

确实c2这个指向结构体的指针的实际数值和第一个成员的地址是一样的。但这并不没关系。赋值中涉及的值的类型都是struct complex,这是赋值正在使用的,所有需要的位都将被复制。

不要不要使用memcpy()来复制结构,绝对没有意义!实际上它可能是一个净负数,因为该结构可以包含填充,赋值运算符(作为一个运算符,其代码生成由编译器控制用于此特定用途)可以处理和跳过,从而节省时间。 memcpy() 函数当然不知道填充,它的工作是复制所有字节,这就是它的作用。

当然,不要使用memcpy() 复制单个int 大小的成员。那只是……不对,不要那样做。

此外,分配是更高级别的,因此更抽象,因此更紧凑,沟通更有效。

当然,如果结构包含它自己的指针(你的没有),你必须小心执行deep copy,并分配指向数据的新实例并复制它。不过,这与实际复制的完成方式无关。

使用struct 赋值。总是。

【讨论】:

  • @mjs 是的,当然。用memcpy() 复制结构本身并没有改变,没有更好。
【解决方案2】:

我你按以下方式更改字段的顺序:

struct complex
{
    int imaginary;
    int real;
);

然后memcpy(&c1.real, &c2->real, sizeof(struct complex)) 将尝试从real 复制字段开始 并且您尝试复制的字节数是整个 结构的大小结构之后会访问内存,因此在某些情况下会导致无效的内存访问,在某些情况下它不会产生任何错误。但是这个操作的结果并不是你所期望的。对于那些,它不会复制字段imaginary

如果您需要复制部分结构 - 这是这样做的方法:

memcpy(&c1.real, &c2->real, sizeof(struct complex) - offsetof(struct complex, real));

其中offsetof 是一个声明为here 的宏。

【讨论】:

    【解决方案3】:

    在这种情况下,更改结构成员的顺序无效。正如您所提到的,结构字段已明确声明。

    当事情变得更复杂时,更容易出错。正如你所做的那样:

    memcpy(&c1.real, &c2->real, sizeof(struct complex));
    

    应该是:

    memcpy(&c1.real, &c2->real, sizeof(c1.real));
    

    越简单越好:

    c1.real = c2->real;
    

    使用memcpy还有另一个问题;你失去了类型安全。有时您希望这样做,但在处理具有相同数据类型的 2 个实体时通常不需要。

    【讨论】:

      【解决方案4】:

      memcpy(&c1.real, &c2->real, sizeof(struct complex)) 很奇怪,因为机器人类型是原子的,所以不需要那种复制。 sizeof(struct complex) 也是错误的,因为它应该是 sizeof(int) (它只有整个结构的 1/2 大小) 简单的赋值就足够了:

      c1.real = c2->real; 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-28
        • 2016-11-14
        • 1970-01-01
        • 1970-01-01
        • 2020-05-23
        • 1970-01-01
        • 1970-01-01
        • 2018-03-29
        相关资源
        最近更新 更多