Search code examples
c++castingstructalignmentpacket

Casting pointer to reuse a buffer


there: I have declaration like this:

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

and in function,I defined a buffer,and valued it:

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

So as I thought, the first 6 bytes of buf should be "68 3A 00 3A 00 68".But the fact is, the first 8 bytes of buf were "68 90 3A 00 3A 00 68 80".And I used:

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

seemingly the numbers "0x68" were not stored as quint8 type but quint16 type to keep consistency with other quint16 types.Anyone has encounted the same problems and has any suggestions.


Solution

  • This is due to alignment. The 16-bit types are aligned on 16-bit adresses. Since your first member only uses 8 bit, 1 byte padding is inserted.

    If you reorder your struct to

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

    it will only use 6 bytes, as no padding is required to align content1.

    See Structure padding and packing for a more detailed explanation.

    Edit after comment:

    So either you use #pragma pack(1) (see: http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=VS.100%29.aspx) (not sure what you mean by

    to set alignment in Qt like "#Pragma" in VC"

    ) or you simply use an array:

    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;