包含C语言结构的struct中的字节分配

时间:2016-07-19 19:56:47

标签: c memory-management struct

我在C程序中有以下结构。

typedef struct
{
  unsigned char msg_id : 8;
  unsigned char msg_num : 8;
} Message_Header_Type;
typedef struct
{
  Message_Header_Type header;
  int msg[32];
} Raw_Message_Type;

我所看到的是,Raw_Message_Type中的标头占用了4个字节,但我只想要它只占2个。我将如何进行此操作?

4 个答案:

答案 0 :(得分:3)

您正在寻找的是 struct packing ,它取决于平台和编译器,详细信息未在C标准中指定。

使用GCC,在32位平台上,您可以执行以下操作以获取大小为2的结构:

typedef struct __attribute__((__packed__))
{
    unsigned char msg_id;
    unsigned char msg_num;
} Message_Header_Type;

来自GCC文件:

  

packed       此属性附加到枚举,结构或联合类型定义,指定使用最小所需内存来表示类型。

答案 1 :(得分:2)

Message_Header_type内的{p> Raw_Message_Type仍然按照您的预期占用2个字节,但编译器为了对齐原因填充结构,因此Raw_Message_Type长度为132个字节而不是你期望的130个字节。这可能是因为32位对齐访问在处理器上更有效。

如果您正在使用gcc,则可以告诉编译器使用#pragma pack对齐2字节边界而不是它正在使用的4字节边界。

typedef struct
{
  unsigned char msg_id : 8;
  unsigned char msg_num : 8;
} Message_Header_Type;
#pragma pack(push, 2) // save current alignment and set to 2-byte boundaries
typedef struct
{
  Message_Header_Type header;
  int msg[32];
} Raw_Message_Type;
#pragma pack(pop) // restore the previous alignment

在文件中使用固定大小的结构时,通常需要这样的特殊包装,但请注意,使用与处理器不同的包装可能会导致(轻)性能损失。在这种特定情况下,您的32 msg [] int现在与您平台的首选路线相距2个字节。

答案 2 :(得分:1)

C实现可以自由地在成员之间,最后或两者之间插入填充struct布局。他们通常这样做是为了对齐目的。编译器通常也提供影响或覆盖填充的机制,但细节必须是特定于实现的。

例如,使用GCC,您可以将packed属性应用于structs

typedef struct __attribute__((__packed__))
{
  unsigned char msg_id : 8;
  unsigned char msg_num : 8;
} Message_Header_Type;

typedef struct __attribute__((__packed__))
{
  Message_Header_Type header;
  int msg[32];
} Raw_Message_Type;

其他一些实施借鉴了GCC的方法;有些人使用pragma来达到同样的目的;还有一些提供其他机制。您需要检查编译器的文档。

答案 3 :(得分:0)

不保证结构对象的成员位字段中使用的位总和的大小。这是因为填充。

在您的情况下,Raw_Message_Type还有其他成员int msg[32];。将两个以上的字节用于目的对齐似乎是合乎逻辑的,这样msg [0]就可以与4字节边界对齐。

很有可能

Message_Header_Type obj;
printf("Size : %zu\n",sizeof(obj));

会给你2作为结果。