转换指针以重用缓冲区

时间:2013-05-01 14:53:38

标签: c++ casting struct alignment packet

有:     我有这样的声明:

typedef struct
{
    quint8  mark1;
    quint16 content1;
    quint16 content2;
    quint8  mark2;
}FrameHead;

在功能上,我定义了一个缓冲区,并对其进行了重视:

quint8 buf[40];
FrameHead *frame  = (FrameHead *)buf;
frame->mark1 = 0x68;
frame->content1 = 0x3A;
frame->content1 = 0x3A;
frame->mark2 = 0x68;

正如我想的那样, buf 的前6个字节应该是“68 3A 00 3A 00 68”。但事实是, buf的前8个字节是“68 90 3A 00 3A 00 68 80”。我用过:

qDebug() << (quint8 *)(++frame) - buf// output "8" but should be "6"

似乎数字“0x68”未存储为 quint8 类型,而是 quint16 类型以保持与其他 quint16 类型的一致性。任何人都已装入同样的问题并有任何建议。

1 个答案:

答案 0 :(得分:1)

这是由于对齐。 16位类型在16位地址上对齐。由于您的第一个成员仅使用8位,因此插入了1个字节的填充。

如果您将结构重新排序为

typedef struct
{
    quint8  mark1;
    quint8  mark2;
    quint16 content1;
    quint16 content2;
}FrameHead;

它只使用6个字节,因为不需要填充来对齐content1

有关更详细的说明,请参阅Structure padding and packing

评论后修改:

所以要么使用#pragma pack(1)(请参阅:http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=VS.100%29.aspx)(不确定你的意思

  

在Qt中设置对齐,如VC“

中的”#Pragma“

)或者您只是使用数组:

typedef quint[6] FrameHead;

....

FrameHead fh1 = {0x68, 0x00, 0x00, 0x00, 0x00, 0x68};
// or 
FrameHead fh2;
memset( fh2, 0, sizeof(FrameHead));
fh2[0] = 0x68;
fh2[5] = 0x68;