struct的大小和相应的变量

Byj*_*yju 3 c

如果我定义一个char变量

char a;
Run Code Online (Sandbox Code Playgroud)

以及具有单个char成员的结构

struct OneChar {
char a;
};
Run Code Online (Sandbox Code Playgroud)

这两个定义在所有编译器中都具有'char'的大小吗?我怀疑的是,如果我们在结构中定义一个char变量,由于内存打包它会比char的大小更大吗?

Jac*_*cob 6

这取决于架构和编译器.对于这种特殊情况,您应该是安全的,但请查看数据结构填充.

这是一段摘录:

x86上C结构的典型对齐方式

数据结构成员按顺序存储在内存中,因此在下面的结构中,成员Data1将始终位于Data2之前,而Data2将始终位于Data3之前:

struct MyData
{
    short Data1;
    short Data2;
    short Data3;
};
Run Code Online (Sandbox Code Playgroud)

如果类型"short"存储在两个字节的存储器中,那么上面描述的数据结构的每个成员将是2字节对齐的.Data1将位于偏移0,Data2位于偏移2处,Data3位于偏移4.此结构的大小为6个字节.

结构的每个成员的类型通常具有默认对齐,这意味着除非程序员另外请求,否则它将在预定边界上对齐.在编译32位x86时,以下典型的对齐对Microsoft,Borland和GNU的编译器有效:

  • char(一个字节)将是1字节对齐的.
  • 短(两个字节)将是2字节对齐的.
  • int(四个字节)将是4字节对齐的.
  • 浮点(四个字节)将是4字节对齐的.
  • 双(8字节)将在Windows上8字节对齐,在Linux上对齐4字节.

这是一个包含各种类型成员的结构,在编译之前总共有8个字节:

struct MixedData
{
    char Data1;
    short Data2;
    int Data3;
    char Data4;
};
Run Code Online (Sandbox Code Playgroud)

编译后,数据结构将补充填充字节,以确保每个成员的正确对齐:

struct MixedData  /* after compilation */
{
    char Data1;
    char Padding0[1]; /* For the following 'short' to be aligned on a 2 byte boundary */
    short Data2;
    int Data3;  
    char Data4;
    char Padding1[3];
};
Run Code Online (Sandbox Code Playgroud)

结构的编译大小现在是12个字节.重要的是要注意,最后一个成员用符合最大类型结构所需的字节数填充.在这种情况下,将3个字节添加到最后一个成员,以将结构填充为长字的大小.

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

请求上面的MixedData结构与一个字节边界对齐将使编译器丢弃成员的预定对齐,并且不插入填充字节.

虽然没有标准方法来定义结构成员的对齐,但是一些编译器使用#pragma指令来指定源文件中的包装.这是一个例子:

#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */

struct MyPackedData
{
    char Data1;
    long Data2;
    char Data3;
};

#pragma pack(pop)   /* restore original alignment from stack */
Run Code Online (Sandbox Code Playgroud)

该结构的编译大小为6个字节.上述指令可在Microsoft,Borland,GNU和许多其他编译器中获得.