地址分配

时间:2013-11-14 15:33:42

标签: c++ visual-studio-2010 visual-c++ mfc

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

2 个答案:

答案 0 :(得分:1)

  

“long c”的地址为“BYTE b”+1?

在大多数情况下没有,因为编译器可能会向字节ab添加填充,以便它们都适合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 ++中的规则相同)。