内存对齐的小妙招
1、为什么需要内存对齐?
只是为了加快CPU对与内存的读取速度
2、内存对齐在结构体中是如何计算结构体大小的?
-
**起始位置按照0x00来计算,**首先qt,vs,windows是默认按照八字节对齐的,linux32位是四字节对齐,64位是8字节对齐。还可以用#pragma (n)手动设置对齐字节数,n只能等于,1,2,4,8,16
-
除结构体第一个变量之外,其余所有变量的起始地址的偏移量必须是n的整数倍(你是默认对齐字节和变量本身大小,两个值之间的最小值)
-
结构体整体大小必须是实际对齐单位的整数倍(计算实际对齐单位是看结构体内最大的变量所占字节数)
-
比如
struct test1 { short a; char b; char c; char f; int d; double e; }x; printf("sizeof(struct test1)=%d\n",sizeof(struct test1));//结果是24
运用上面得方法计算如下:
char a为0x00-0x02;2字节char b为0x02-0x03;1个字节(偏移量是自身大小的整数倍就行所以是1)
char c为0x03-0x04为1字节,
char f为0x04-0x05;1字节,
int d为0x08-0x11(int的偏移量必须是4的整数倍,所以只能为0x08-0x0b),
double e;地址为0x16-0x23;(起始地址必须是8的整数倍),
然后现在整个结构体大小是24,是最小对齐数8的整数倍,ok
-
结构体中有数组怎么解决,比如说加入char c[11],这里直接看作11个char去处理就好了
比如
struct test1 { short a; char b; char c; char f; int d; double e; char cc[11]; }x; printf("sizeof(struct test1)=%d\n",sizeof(struct test1));//结果是40
char a为0x00-0x02;2字节
char b为0x02-0x03;1个字节(偏移量是自身大小的整数倍就行所以是1)
char c为0x03-0x04为1字节,
char f为0x04-0x05;1字节,
int d为0x08-0x11(int的偏移量必须是4的整数倍,所以只能为0x08-0x0b),
double e;地址为0x16-0x23;(起始地址必须是8的整数倍),
char cc[11],地址就是0x23-0x33,
这时整个结构体大小是34,不是最小对齐量8的倍数,所以,结构体大小应该是40
-
对于结构体中嵌套结构体怎么计算
1、把嵌套进去的子结构体也当作一个变量,
2、计算该结构体的偏移地址,应该是该结构体内的结构体内最大内存的变量和默认的偏移量的整数倍
如
struct son { short a; char b; char c; char f; int d; double e; char cc[11]; }son;//大小是40 struct parent { char aa; int bb; son son1; }; printf("sizeof(struct parent)=%d\n",sizeof(struct parent));//答案48
计算:
parent里面开始是
char aa 为0x00-0x01;
int bb;为0x03-07;
struct son son1为0x07-0x47;所以大小是48
附录:常用字节数(32位机):
int 一个字 32位,4字节
short 半个字 16位,2字节
long 一个字 32位,4字节
char 1字节
float 一个字 32位 ,4字节
double 两个字 64位, 8字节
-