如果我定义一个char变量
char a;
Run Code Online (Sandbox Code Playgroud)
以及具有单个char成员的结构
struct OneChar {
char a;
};
Run Code Online (Sandbox Code Playgroud)
这两个定义在所有编译器中都具有'char'的大小吗?我怀疑的是,如果我们在结构中定义一个char变量,由于内存打包它会比char的大小更大吗?
这取决于架构和编译器.对于这种特殊情况,您应该是安全的,但请查看数据结构填充.
这是一段摘录:
x86上C结构的典型对齐方式
数据结构成员按顺序存储在内存中,因此在下面的结构中,成员Data1将始终位于Data2之前,而Data2将始终位于Data3之前:
Run Code Online (Sandbox Code Playgroud)struct MyData { short Data1; short Data2; short Data3; };如果类型"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个字节:
Run Code Online (Sandbox Code Playgroud)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]; };结构的编译大小现在是12个字节.重要的是要注意,最后一个成员用符合最大类型结构所需的字节数填充.在这种情况下,将3个字节添加到最后一个成员,以将结构填充为长字的大小.
通过更改编译器对结构成员的对齐(或"打包"),可以更改结构的对齐以减少它们所需的内存(或符合现有格式).
请求上面的MixedData结构与一个字节边界对齐将使编译器丢弃成员的预定对齐,并且不插入填充字节.
虽然没有标准方法来定义结构成员的对齐,但是一些编译器使用#pragma指令来指定源文件中的包装.这是一个例子:
Run Code Online (Sandbox Code Playgroud)#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 */该结构的编译大小为6个字节.上述指令可在Microsoft,Borland,GNU和许多其他编译器中获得.