memcpy结构的一部分

时间:2011-03-14 21:58:27

标签: c++ memcpy pod

我有一个struct / class,它是partiall Plain Old Data(POD)。

struct S {
  // plain-old-data structs with only arrays and members of basic types (no pointers);
  Pod1 pod1;
  Pod2 pod2;
  Pod3 pod3;
  Pod4 pod4;
  vector<int> more;
};

我经常复制S类的对象。 我想用memcpy复制它,但S :: more阻止了它。 我想避免调用4个memcpy,并将其全部用于一个额外的性能。 我应该这样做吗?

memcpy(s1, s2, sizeof(Pod1) + sizeof(Pod2) + sizeof(Pod3) + sizeof(Pod4);

我无法将它们打包在单独的结构中,因为它会破坏使用pod1-pod4的所有代码。

什么是最佳解决方案?

4 个答案:

答案 0 :(得分:10)

最好的解决方案是依靠C ++自动复制构造函数和复制运算符。然后,编译器有机会理解您的代码并对其进行优化。尽量避免使用C ++代码中的memcpy。

如果您只需要复制部分结构,请为其创建一个方法:

struct S {
  // plain-old-data structs with only arrays and members of basic types (no pointers);
  Pod1 pod1;
  Pod2 pod2;
  Pod3 pod3;
  Pod4 pod4;
  vector<int> more;
};

void copyPartOfS(S& to, const S& from)
{
  s.pod1 = from.pod1;
  s.pod2 = from.pod2;
  s.pod3 = from.pod3;
  s.pod4 = from.pod4;
}

...

S one, two;
one = two; // Full copy
copyPartOfS(one, two); // Partial copy

答案 1 :(得分:2)

作为@Erik said,您拥有的代码因填充而无效。

但是,由于您没有使用任何访问声明,因此编译器需要按照与源代码相同的顺序存储字段,因此您可以这样做:

struct S {
  // plain-old-data structs with only arrays and members of basic types (no pointers);
  Pod1 pod1;
  Pod2 pod2;
  Pod3 pod3;
  Pod4 pod4;
  vector<int> more;
};

memcpy(&s1.pod1, &s2.pod1, (char*)(1 + &s1.pod4) - (char*)(&s1.pod1));

答案 2 :(得分:1)

这是不安全的,不能保证结构被打包,它们之间可能有空的空间用于对齐目的。

使用赋值和/或复制构造是安全的,并且在使用分析器进行验证之前,它与memcpy一样快。)。

编辑:如果你真的想使用memcpy,这是一个可能但可怕的解决方案:

struct S1 {
  Pod1 P1;
  Pod2 P2;
};

struct S : S1 {
  vector<int> more;
};


void copy(S & Dest, S const & Src) {
  memcpy(&Dest, &Src, sizeof(S1));
  Dest.more = Src.more;
}

答案 3 :(得分:1)

void CopyPods(Struct S& s1, Struct S& s2)
{
  s2.pod1=s1.pod1;
  s2.pod2=s1.pod2;
  s2.pod3=s1.pod3;
  s2.pod4=s1.pod4;
}

让编译器/链接器为你优化它:它会比你做得更好。并且你消除了将令人讨厌的错误带入游戏的风险(例如对齐,打包......)。