2

我有一个结构来表示一个 ip 标头

struct IPHDR // the ip header
{
    unsigned char VER : 4;
    unsigned char IHL : 4;
    unsigned char DSCP : 6;
    unsigned char ECN : 2;
    unsigned short len;
    unsigned short id;
    u_char Reserved:1; //Zeroes
    u_char DF:1; //Dont Fragment
    u_char MF:1; //More Fragment
    unsigned short FragOffset : 13;
    u_char ttl;
    u_char protocol;
    u_short checksum;
    struct in_addr src;
    struct in_addr dst;
} ;

sizeof(IPHDR) 在应该返回 20 时返回 24。出了什么问题?

4

2 回答 2

3

这是因为您的结构被填充以克服这个问题,您可以使用#pragma pack 编译器指令,如下所示:

#pragma pack(push)
#pragma pack(1)
struct IPHDR // the ip header
{
   unsigned char VER : 4;
   unsigned char IHL : 4;
   unsigned char DSCP : 6;
   unsigned char ECN : 2;
   unsigned short len;
   unsigned short id;
   u_char Reserved:1; //Zeroes
   u_char DF:1; //Dont Fragment
   u_char MF:1; //More Fragment
   unsigned short FragOffset : 13;
   u_char ttl;
   u_char protocol;
   u_short checksum;
   struct in_addr src;
   struct in_addr dst;
 } ;
 #pragma pack(pop)

阅读有关填充和对齐的更多信息:数据结构对齐

于 2013-07-07T13:10:35.567 回答
1

这是因为您的结构被迫进行内存对齐。简而言之,结构的总大小应该是任何结构成员的最大对齐方式的倍数。这个要求来自处理器以块而不是单个字节读取内存的事实。有人说内存对齐是现代处理器的一个限制,它通常可以通过执行 4 个低效的单字节提取而不是一个有效的字提取来解决,但是许多语言说明者认为将它们取缔并强制所有内容都更容易对齐。

通常通过重新实现结构中的字段序列,您可以实现结构的不同对齐方式和大小。

从提供的链接:

通过重新排序结构成员或更改编译器对结构成员的对齐(或“打包”),可以更改结构的对齐以减少它们所需的内存(或符合现有格式)。

于 2013-07-07T13:25:23.913 回答