一、数据模型
各平台使用的数据模型共分为五种,分别为LP32、ILP32、LP64、ILP64和LLP64。其中,I->int,L->long,P->pointer,LL->long long,数字代表数据类型的字节长度。例如:ILP32代表int、long和pointer的长度为32位(4字节),LLP64代表long long和pointer数据类型的长度为64位(8字节)。
目前,Unix系统(64位)使用的都是LP64模型,Unix(32位)和Windows(32位)都使用的ILP32模型,64位Windows使用的是LLP64模型。
总体上看,LP64,ILP64,LLP64是64位平台上的数据模型,ILP32和LP32是32位平台上的数据模型。
二、常用数据类型长度
LP32 | ILP32 | LP64 | ILP64 | LLP64 | |
---|---|---|---|---|---|
char | 1 | 1 | 1 | 1 | 1 |
short | 2 | 2 | 2 | 2 | 2 |
int | 4 | 4 | 4 | 8 | 4 |
long | 4 | 4 | 8 | 8 | 4 |
long long | 8 | 8 | 8 | 8 | 8 |
pointer | 4 | 4 | 8 | 8 | 8 |
所有数据模型中,float为4字节,double为8字节。
指针类型存储的是地址变量,32位系统的地址位数为32bits,则指针长度为4字节,64位系统的地址位数为64bits,则指针长度为8字节。指针与数据模型无关。
三、字节对齐问题
1. 字节对齐
在计算机系统中,字节对齐跟数据在内存中的存储位置有关。如果一个数据变量的存储地址是其对应长度的整数倍,那么该变量为自然对齐。例如:某个整型变量的存储地址为0x00000004,则该变量为自然对齐。下表展示了其他相关概念。
定义 | |
---|---|
自身对齐值 | 操作系统中的数据类型的固定长度 |
指定对齐值 | 人为指定的对齐值,设置方法:#pragma pack(value) |
有效对齐值 | 自身对齐值和指定对齐值中最小的那个 |
2. 为什么要字节对齐?
字节对齐的根本原因是提高CPU访问数据的效率。例如,处理器每次从存储器中读取四个字节长度的数据,则当存储地址是4的倍数时,整型数据一次存储器操作就可以完成读写,否则我们需要两次存储器操作才能完成任务。总之,字节对齐使得读写次数最少,从而提高数据访问效率。
3. 如何处理字节对齐?
对于标准的数据类型,只要保证存储地址是其长度的整数倍即可。
对于结构体数据,其内部的所有数据类型都需要对齐。
对齐规则:
所有数据类型的存储地址都应该是其对应有效对齐值的整数倍。
结构体中的对齐填充补齐:
对于结构体中的成员变量,当不满足对齐规则时,需要在其前面填充一些字节保证当前成员是字节对齐的。