字节对齐
什么是字节对齐
计算机中内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问某种基本数据类型,但是实际上,计算机并非逐字节大小读写内存,而是以2,4,或8的 倍数的字节块来读写内存,如此一来就会对基本数据类型的合法地址作出一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。
对齐准则是什么
总的来说,字节对齐有以下准则:
-
结构体变量的首地址能够被其对齐字节数大小所整除。
-
结构体每个成员相对结构体首地址的偏移都是成员大小的整数倍,如不满足,对前一个成员填充字节以满足。
-
结构体的总大小为结构体对最大成员大小的整数倍,如不满足,最后填充字节以满足。
但是,复合结构的结构体,以及位域组成的结构体,其字节对齐方法是什么呢?来看一下例子。
复合结构体:
#include<iostream>
//定义结构体CC
typedef struct cc
{
unsigned char a:2;
unsigned char b:1;
unsigned char c:2;
}CC;
//定义结构体BB
typedef struct bb
{
int id;
double weight;
float height;
}BB;
//定义结构体AA
typedef struct aa
{
CC c;
char name[2];
int id;
short score;
short grade;
BB b;
}AA;
int main(){
int n=0;
CC c;
BB b;
AA a;
std::cout<<"c的长度:"<<sizeof(c)<<std::endl;
std::cout<<"b的长度:"<<sizeof(b)<<std::endl;
std::cout<<"a的长度:"<<sizeof(a)<<std::endl;
std::cin>>n;
return 0;
}
运行结果:
c的长度:1
b的长度:24
a的长度:40
结构体c中,三个位域总共占据5bit,不到一个字节,可以用一个字节将结构体c存放。
结构体b中,根据字节对齐原则,字节存放规则为:
4 Bytes(id)+4 Bytes(填充)+8 Bytes(weight)+8 Bytes(height)=24 Bytes
结构体a中,存在复合结构体,复合结构体的字节对齐原则是:
- 首先判断对齐值,一般类型的变量的对齐值为类型变量的长度,如int:4Bytes;复合结构体的对齐值是子结构体中最长的数据类型,如本例中结构体a的子结构体b的对齐值是double:8Bytes。
- 对齐值要满足以上三点字节对齐原则。
结构体a中,根据字节对齐原则,字节存放规则为:
1Byte(c)+2Bytes(name[2])+1Byte(填充)+4Bytes(id)+2Bytes(score)+
2Bytes(grade)+4Bytes(填充,满足复合结构体原则)+24Bytes(结构体b) = 40Bytes