一、字节对齐/结构体对齐是什么
如图,sizeof函数可以看到变量长度,比如sizeof(char)就是一个字节,而关于数组的,如下图
打印结果:
10
20
40
如果是这样的,那么已经越界了,但是C语言不检查越不越界,对于VC6就是一个下标为10的元素,实际上在sizeof眼中只是下表为10的元素
打印结果:
12
8
int + 2*char因该是6,打印结果应该是6,结构体里面的类型都是一样的,但是一个打印出来12,8,也就是说占用空间不一样
如果把main函数改成这样:
也就是说sizeof可以放类型,也可以放变量名,为什么会有类型一样但是结构体占用空间不一样的情况,这就是字节对齐/结构体对齐的知识点
二、字节对齐/结构体对齐
1.本质
效率与空间二选一的结果
2.对齐参数
一般取值是1,2,4,8
基本用法:
#pragma pack(n)
结构体
#pragma pack()
n是字节对齐数,如果比sizeof小,那么偏移量以这个为准,就是说偏移量取n和sizeof里的最小值
比如上面那个题,int是4,而参数为4,则以4为准,64是8,参数为4,就以4为准,char为1,参数为4,就以1为准
当参数n为1时
中间一个地方都没浪费,节省空间
打印结果:13
内存分配:
执行,第一个分配了四个空间,第二个从ebp-0ch指令到ebp-4,分配了8个,先写2再补0,第三个变量分配了1个字节
如果是两个的话:
前面int4个字节,longlong8个,里面有个char类型,一个字节,大小不一致以小的为准,分配的时候应该按照1来分
第二条规则:结构体最后对齐的空间,应该是参数的整数倍,13不是2的整数倍,所以后面补一个字节,最后占用的空间就是14字节
打印结果:14
如果参数为4
8个字节分4个偏移,而13不是4的整数倍,补齐3个,把参数改成4
打印结果:16
参数为8:
如果不够,重新起,8字节对齐,必须是8的整数倍,现在是24,试一下
对齐原则:
回到之前的12和8的问题
这里的默认对齐参数是8,看到规则1,第一个从0开始放,先放一个啊,以后每个成员都是这个成员本身的整数倍存储,比如第一个s1
a 0 0 0
b b b b
c 0 0 0
因为4比8小,所以对齐是用8来参考,不是4,总共12
对于S2:
a a a a
b c 0 0
分别与8逼,4小,所以用4来做偏移,总共8的内存
建议:从小到大写
三、typedef
给现有类型定义新的名字