【问题标题】:Difference between memcpy and '=' when copying simple struct复制简单结构时 memcpy 和 '=' 之间的区别
【发布时间】:2014-04-26 16:51:26
【问题描述】:

考虑复制一个不需要特殊复制语义的简单结构。

struct A
{
    char i
    int i;
    long l;
    double b;
    //...maybe more member
}
struct A a;
a.c = 'a'; //skip other member just for illustrate
struct A b;
memset(&a, 0, sizeof(a));
b.c = a.c;
//...for other members, the first way to assign
memcpy(&b, &a, sizeof(b)); //the second way
b = a;    //the third way

这 3 种方法做同样的事情,而且似乎所有方法都是正确的。我曾经使用 'memcpy' 来复制简单的结构,但现在似乎 '=' 可以做同样的事情。那么使用memcpy和'='有什么区别吗?

【问题讨论】:

  • memcpy 将复制成员之间的填充。
  • memset : memset(对象的地址,设置字符,大小)
  • 感谢@BLUEPIXY,已编辑。
  • @Barmar 和= 可能会也可能不会;这取决于实施。
  • memcpy() 还可以方便地一次性复制结构数组。

标签: c++ c struct memcpy


【解决方案1】:

memcpy 将结构视为一个连续的字节数组,并复制所有字节。因此,它总是会复制成员之后的填充字节。

= 只需要复制成员。它可能会也可能不会复制填充。

【讨论】:

  • tks,Barmar,这是否意味着 '=' 与 b.c = a.c ...etc 相同?
  • 是的,这是必需的语义。它可能会被优化成不同的代码——编译器可以把它变成类似memcpy的东西。
【解决方案2】:

我现在会养成使用= 而不是memcpy 的习惯。在 C 中,差异充其量是最小的,但是一旦你毕业到 C++,如问题所示,差异是巨大的。例如考虑

struct C {
  C() { }
  ~C() { } 
}

C local1;
C local2;
memcpy(&local2, &local1, sizeof(C));

在这种情况下,local2 的构造函数在声明点运行。但是,该值的析构函数永远不会运行。相反,它的成员被神奇地替换为memcpy,并且析构函数在memcpy 位上运行。如果C 碰巧分配了任何资源,这很容易导致泄漏。

【讨论】:

    【解决方案3】:

    这三种方法中的任何一种——手动分配每个成员,分配整个结构,或者使用memcpy——都会导致b的所有成员与a的对应成员相同,这就是所有你应该关心。潜在的差异在于填充字节的值——memcpy 将复制它们,分配单个成员不会,并且分配整个结构可能会也可能不会——这取决于实现。有些实现将只使用memcpy 来分配结构,有些会逐个分配成员,有些会根据结构大小等因素执行其中一种或另一种。

    我推荐使用结构赋值——它是最简单、最短且最面向问题的。将实现细节留给编译器。此外,在 C++ 中,您可以自己定义赋值运算符以获得更大的控制力和灵活性,而 memcpy 不受欢迎,并且可能对类产生不良影响(请参阅 JaredPar 的回答)。

    【讨论】:

    • @JasonC 名单是 OP,他们正在询问 C (但对未来的 C++ 编程感兴趣)。并且复制构造函数不一定会导致b 的成员与a 的成员相同,这与其他三种方法不同。
    猜你喜欢
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 2014-11-01
    • 2013-07-01
    • 1970-01-01
    相关资源
    最近更新 更多