类的地址分配

address assignment of class

本文关键字:分配 地址      更新时间:2023-10-16

我有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 类和 CPaccet 中分配的?如果我像上面一样在"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 class"呢?

"long c" 将具有 "BYTE b"+1 的地址 ?

在大多数情况下不会,因为编译器可能会向字节ab添加填充,以便它们都适合 4 个字节,从而导致 CHeader 总共 12 个字节而不是 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) );

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

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

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

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