0

我有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 Class 和 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 类”呢?

4

2 回答 2

1

您对会员地址的假设是错误的。编译器可能会插入一些填充,以保持内存对齐 [1]。

这就是为什么你的 memcpy 不起作用。您必须获取 mRcvData 块并逐个成员分配给 packet->mHeader 的成员。

[1] - http://en.wikipedia.org/wiki/Data_structure_alignment

[2] - C 结构中的内存对齐(即使是关于 C 结构,规则在 c++ 中也是相同的)。

于 2013-11-14T15:58:52.143 回答
1

"long c" 的地址是 "BYTE b"+1 吗?

在大多数情况下不会,因为编译器可能会在字节中添加填充ab以便它们都适合 4 个字节,导致总共 12 个字节CHeader而不是 10 个(优化)。因此,执行 memcpy 并手动将字节分配给成员不会产生相同的结果。有关更多详细信息,请参阅内容。

如果您想直接分配字节(我认为这被标记为未定义的行为),您可以这样做:

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) );
于 2013-11-14T15:52:48.347 回答