C语言结构体内存的对齐知识详解
什么是结构体内存对齐?
结构体内存对齐是指编译器为了提高数据存取效率,在变量定义时进行的一种内存填充策略。根据数据类型及所在位置的不同,编译器在结构体内部进行填充,使它的大小为其成员大小的整数倍。
为什么需要结构体内存对齐?
在进行数据传输时,通常以字节为传输单位,如果结构体内存没有按照规定的方式进行对齐,则运行效率将极低,甚至不保证正确传输,另外在x86-64体系架构下,未对齐的数据导致程序异常退出。
结构体内存对齐规则
- 结构体变量的起始地址必须是其内部最大元素大小的整数倍。
- 结构体变量中每个元素被安排到偏移地址为其大小的倍数的位置,如果当前位置不为该元素大小的倍数,必须进行填充。
- 结构体的总大小为结构体最宽基本类型成员大小的整数倍。
示例一
struct S
{
char a;
int b;
char c;
};
printf("%d", sizeof(S)); // 12
对于以上结构体S,起始地址为0x0,可分为3个部分:
- a 的偏移地址为0x0,大小为1个字节;
- b 的偏移地址为0x4,大小为4个字节;
- c 的偏移地址为0x8,大小为1个字节;
因为a和b之间存在3个字节的空隙,所以填充了2个字节,而c后面没有空隙,因此结构体S的大小为12字节。
示例二
struct S
{
char a;
double b;
char c;
};
printf("%d", sizeof(S)); // 16
对于以上结构体S,起始地址为0x0,可分为3个部分:
- a 的偏移地址为0x0,大小为1个字节;
- b 的偏移地址为0x8,大小为8个字节;
- c 的偏移地址为0x10,大小为1个字节;
由于double类型的大小为8个字节,所以a和b之间空出7个字节,而c后面没有空隙,因此结构体S的大小为16字节。
如何优化结构体内存对齐?
- 可以使用
__attribute__((aligned(n)))
,强制指定对齐字节数,如下:
struct S
{
char a;
int b;
char c;
} __attribute__((aligned(4)));
printf("%d", sizeof(S)); // 12
- 将占用内存空间较大的成员放在结构体的末尾,如下:
struct S
{
char a;
char c;
double b;
};
printf("%d", sizeof(S)); // 16
以上就是结构体内存对齐的详细攻略,希望能对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言结构体内存的对齐知识详解 - Python技术站