memcpy和copy之间的区别

Ete*_*ner 3 c c++ memcpy

Struct A
{
   uint16_t len;
   uint8_t  cnt;
   uint8_t  unit;
   uint32_t seq; 
};
Run Code Online (Sandbox Code Playgroud)

这个结构A被序列化为一个char *buf.如果我想反序列化各个值,例如:

uint16_t len = 0;
memcpy(&len, buf, sizeof(len));
Run Code Online (Sandbox Code Playgroud)

或者我可以做

uint16_t len = (uint16_t) buf;
Run Code Online (Sandbox Code Playgroud)

哪一个更好或者两者都相同?

如果我这样做的话,也要对整个结构进行反序列化

A tmp;

memcpy(&tmp, buf, sizeof(A));
Run Code Online (Sandbox Code Playgroud)

这工作正常还是我应该担心编译器的填充等?

das*_*ght 8

当数据被复制到char[]缓冲区时,它可能无法在内存中正确对齐以便作为多字节类型进行访问.将数据复制回以struct恢复正确对齐.

如果我想反序列化各个值,例如:

uint16_t len = 0;
memcpy(&len, buf, sizeof(len));
Run Code Online (Sandbox Code Playgroud)

假设您已复制structbuf,这是完全有效的,因为该语言保证初始成员将与结构的开头对齐.然而,在浇铸bufuint16_t*是无效的,因为很多不是在内存中正确对齐缓冲区作为解决uint16_t.

请注意,获取结构的元素而不是初始元素需要计算适当的偏移量:

uint32_t seq;
memcpy(&seq, buf+offsetof(struct A, seq), sizeof(seq));
Run Code Online (Sandbox Code Playgroud)

如果我这样做的话,也要对整个结构进行反序列化

A tmp;
memcpy(&tmp, buf, sizeof(A));
Run Code Online (Sandbox Code Playgroud)

这工作正常还是我应该担心编译器的填充等?

这样可以正常工作.struct当您将其复制到其中时嵌入的任何填充buftmp与实际数据一起返回.

  • @EternalLearner理想情况下,您开发了一个正式的*协议*,用于串行(通过网络或其他方式)传输数据,然后与发送者和接收者一起遵守该协议.如果您明智地设置协议,那么这样做具有额外的优势,与平台无关; 结构转储到缓冲区,发送,然后缓冲区转储到结构中的东西非常缺乏. (2认同)