我有2个班级,
#define HEADER_SIZE sizeof(CHeader)
#define BODY_SIZE 5132
#define PACKET_SIZE sizeof(CPacket)
Class CHeader
{
BYTE a;
BYTE b;
long c;
long d;
}
Class CPacket : CObject
{
CHeader mHeader;
BYTE mBody[BODY_SIZE];
CPacket() { }
virtual ~CPacket() { }
}
在其他课程中,我有
void func()
{
BYTE mRcvData[PACKET_SIZE];
CPacket *packet = new CPacket();
memcpy(packet->mHeader, mRcvData, HEADER_SIZE);
}
通过套接字从客户端接收mRcvData,因此我想将数据保存到CPacket实例中。要首先将mRcvData的标题部分复制到数据包中,我使用了“memcpy”函数,但它不起作用。
我的问题是,
首先,我怎样才能让它按照我的意图运作?
其次,如何在CHeader类和CPacket中分配成员变量的地址? 如果我在上面的“BYTE b”之后指定“long c”,“long c”的地址是“BYTE b”+1?
我的意思是,我的逻辑是,例如,
Address of CHEADER Class : @ 1000
Address of variable "a" in CHEADER Class : @ 1000
Address of variable "b" in CHEADER Class : @ 1001 (because "a" consumes 1 byte)
Address of variable "c" in CHEADER Class : @ 1002 (because "b" consumes 1 byte)
Address of variable "d" in CHEADER Class : @ 1006 (because "c" consumes 4 byte)
这是真的吗?怎么样“CPacket类”?
答案 0 :(得分:1)
“long c”的地址为“BYTE b”+1?
在大多数情况下没有,因为编译器可能会向字节a
和b
添加填充,以便它们都适合4个字节,从而导致CHeader
的总共12个字节而不是10(优化)。因此,执行memcpy并手动为成员分配字节不会产生相同的结果。有关详细信息,请参阅this。
如果你想直接分配字节(我认为它被标记为未定义的行为),你可以这样做:
BYTE mRcvData[PACKET_SIZE];
CPacket *packet = new CPacket();
packet->header = reinterpret_cast<CHeader*>(&mRcvData[0]);//let the compiler do memcpy for you
//memcpy only on the body
memcpy( packet->mBody, &mRcvData[sizeof(CHeader)] , min(PACKET_SIZE - sizeof(CHeader), BODY_SIZE) );
答案 1 :(得分:1)
你对会员地址的假设是错误的。 编译器MIGHT插入一些填充,以保持内存对齐[1]。
这就是为什么你的memcpy不起作用的原因。您必须获取mRcvData的块并按成员分配给packet-&gt; mHeader的成员。
[1] - http://en.wikipedia.org/wiki/Data_structure_alignment
[2] - Memory alignment in C-structs(即使它是关于C结构,c ++中的规则相同)。