当将指针强制转换为指向包含联合的结构时
我对包含联合的结构有疑问。问题是:
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
为 0x101
且 value
为 48
?
机器是小端字节序。
请帮我解决这个问题...
I have problem with a struct containing union. Here is the problem:
typedef struct
{
unsigned char Type;
union
{
unsigned char Length;
unsigned __int16 Length2;
}
char Value[0];
} TLV_TUPLE, *PTLV_TUPLE;
If Type == 0x40h
, I use Length2
, otherwise use Length
.
I use this structure to read this file stream (In hex):
FE 01 01 40 12 00 30 …
Now the code:
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
Then as I check the value of pTlv with debugger, I see this:
pTlv->Type == FE
pTlv->Length == 1
pTlv->Length2 == 4001
pTlv->Value == 12
Shouldn't Length2
be 0x101
and value
be 48
?
machine is little endian.
Please help me with this...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里发生的情况是,结构被填充了一个额外的字节,以便联合可以正确对齐。
FE
后面的01
是填充,实际的联合从下一个字节开始。这是因为联合的对齐要求受到其部件的对齐要求的影响。由于 Length2 需要在两字节边界上对齐,因此在其之前插入一个填充字节以确保发生这种情况。
如果您读入的流是
FE FF 01 40 12 00 30 ...
,您仍然会得到相同的值。顺便说一句,我认为
“Length2不应该是0101,值不应该是48吗?”
实际上应该读取64(0x40)
而不是48(0x30)
。我认为这是你的拼写错误。如果您需要结构没有填充,则没有标准方法可以做到这一点,但您的编译器应该提供一种方法。例如,您可以在
gcc
中使用类似属性的内容:其他环境可能提供
#pragma pack
或类似的内容来达到相同的目的。What's happening here is that the structure is being padded with an extra byte so that the union can be correctly aligned.
The
01
following theFE
is padding, the actual union starts at the next byte. That's because the alignment requirement for a union is affected by the alignment requirements of its parts.Since
Length2
has a requirement to be aligned on a two-byte boundary, a padding byte is inserted before it to ensure this happens.If the stream you read in was
FE FF 01 40 12 00 30 ...
, you would still get the same values.As an aside, I think
"Shouldn’t Length2 be 0101 and value be 48?"
should actually have read64 (0x40)
rather than48 (0x30)
. I assume that was a typo on your part.If you need the structure to not have padding, there's no standard way to do it but your compiler should provide a way. For example, you could use something like attributes in
gcc
:Other environments may provide a
#pragma pack
or something similar to acheive the same end.