C语言程序中结构体的内存对齐详解
Fug_Lee 人气:0一、为什么存在内存对齐
1.平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2. 性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
总的来说结构体的内存对齐是拿空间来换取时间的做法。
二、结构体的内存对齐四规则
默认情况:默认的对齐值 8字节
1.基本数据类型有一个对齐值
2.自定义类型有一个对齐值 = 内部成员类型的最大值
3.程序的指定对齐值:#pragma pack(n) n == 2的幂次方 n可以等于2 4 8 16 …
4.程序的有效对齐值:程序的指定对齐值和数据类型对齐值得较小值
三、举例
例1
typedef struct Test //8 { char a; //1 + 7 double b; //8 int c; //4 + 4 }Test; void main() { Test t; printf("Test size = %d", sizeof(Test)); }
分析:
char类型占一个字节,double类型占八个字节,int占四个字节;根据其对齐规则,内部成员类型的最大值为double(8个字节),所以char类型要补齐另外的七个字节,加上int的四个字节,一共是:1+7+8+4 = 20,此时20不是8的倍数,因此int要补四个字节。
结果:
例2
typedef struct Test //8 { char a; //1 + 3 int c; //4 double b; //8 }Test; void main() { Test t; printf("Test size = %d", sizeof(Test)); }
分析同上
结果:
例3
typedef struct Test { short a; //2 + 6 struct { int b; //4 + 4 double c;//8 char d; //1 + 7 }; int e; //4 + 4 }Test; void main() { Test t; printf("Test size = %d", sizeof(Test)); }
结果:
例4 程序中有指定对齐值时
#pragma pack(2) typedef struct Test { short a; //2 struct { int b; //4 double c;//8 char d; //1 + 1 };//14 int e; //4 }Test; void main() { Test t; printf("Test size = %d", sizeof(Test)); }
结果:
加载全部内容