当指针指向包含union的结构时

时间:2011-03-06 18:07:00

标签: c pointers casting struct unions

我对包含union的结构有问题。这是问题所在:

typedef struct
{
    unsigned char Type;                          
    union
    {
        unsigned char Length;
        unsigned __int16 Length2;
    }
    char Value[0];    
} TLV_TUPLE, *PTLV_TUPLE;

如果Type == 0x40h,我使用Length2,否则请使用Length

我使用此结构来读取此文件流(十六进制):

FE 01 01 40 12 00 30 …

现在代码:

unsigned char * m_pTLV;

/*code here to  let m_pTLV points to the
  first byte of the file, that is, point to 'FE' */

PTLV_TUPLE pTlv = (PTLV_TUPLE)m_pTLV; // cast m_pTLV to PTLV_TUPLE

然后当我用调试器检查pTlv的值时,我看到了:

pTlv->Type == FE
pTlv->Length == 1
pTlv->Length2 == 4001
pTlv->Value == 12

Length2 0x101value 48不应该是{{1}}吗?

机器是小端。

请帮帮我...

1 个答案:

答案 0 :(得分:2)

这里发生的是结构用一个额外的字节填充,以便联合可以正确对齐。

01之后的FE是填充,实际联合从下一个字节开始。这是因为联合的对齐要求受其各部分的对齐要求的影响。

由于Length2需要在双字节边界上对齐,因此在它之前插入填充字节以确保发生这种情况。

如果您输入的信息流为FE FF 01 40 12 00 30 ...,您仍会获得相同的值。


顺便说一句,我认为"Shouldn’t Length2 be 0101 and value be 48?"实际上应该阅读64 (0x40)而不是48 (0x30)。我认为这是你的错字。


如果需要结构没有填充,那么没有标准方法可以做到这一点,但是你的编译器应该提供一种方法。例如,您可以使用gcc中的属性:

typedef  struct {
    unsigned char Type;                          
    union {
        unsigned char Length;
        unsigned __int16 Length2;
    }
    char Value[0];    
} __attribute__ ((aligned(1),packed)) TLV_TUPLE;

其他环境可能提供#pragma pack或类似的东西来实现同一目的。