C语言查缺补漏(七)结构体内存对齐原则

忽略点七:结构体内存对齐原则

​ 直到前几个星期做了一道选择题才知道,结构体元素的声明顺序可能影响结构体使用时所需的内存大小!!!

​ 一查才知道,在C语言中结构体有内存对齐原则,这个原则可以总结为两点:

——数据成员对齐规则:

​ 结构体或联合体的数据成员,第一个数据成员放在offset为0的地方,以后每个成员存储的起始位置为该成员大小(当该成员为基本类型时)或者该成员的最大子成员大小(当该成员为数组,结构体等时)的整数倍位置

——收尾:

​ 结构体所占内存的总大小,必须是它内部最大成员所占内存大小的整数倍(像数组,结构体等成员在计算时按其成员的最大成员所占内存算),不是要补齐

​ 对于以上的文字,大家可能会不理解,给大家上份代码理解一手:

struct bb {
    int id;     	//所占内存位置为0~3
    double weight;	//所占内存位置为8~15
    char s[10];		//所占位置为16~25
};					//整个结构体bb所占内存位置为 0~31	

struct aa {
    char name[2]; 	//所占内存位置为0~1
    bb	b;			//所占内存位置为8~39;
    int age;		//所占内存位置为40~43;
};					//整个结构体aa所占内存位置0~47

在结构体bb中:

​ int类型id为4字节,所以占用0~3位置

​ double类型weight为8字节,它的起始位置必须是8的整数倍,所以它的起始位置为8,占用位置为8~15

​ char型数组s中最大成员单个char是1字节,所以char数组的起始位置必须是1的整数倍,所以它的起始位置为16,而数组长度为10,总占用字节为10,所以占用位置为16~25

​ 在结构体bb中,最大成员为double型的weight(有同学会说char s[10]最大,为什么不是char s[10]?因为char s的最大成员所占内存为1,s按照1进行比较),所以结构体bb总占用内存必须为8的整数倍,所以结构体bb的总内存地址为0~31

在结构体aa中:

​ char型数组name数组长度为2,单个char占1字节,数组总共占两字节,所以占用位置为0~1

​ bb型结构体b中最大成员为double型的weight,所以bb类型的起始位置必须是8的整数倍,也就是8,而结构体bb总占用内存是32,所以占用b位置为8~39

​ int型age为4字节,所以起始位置必须是4的整数倍,也就是40,所以它占用的位置是40~43

​ 在结构体aa中,最大成员是结构体b(它的最大成员weight占用内存为8),所以结构体aa总占用内存必须是8的整数倍,所以结构体aa的总内存地址为0~47

​ 讲到这儿,我们会有一个疑问,C语言为什么要有对齐原则呢?多浪费空间呀!大家可能知道桶排这种算法,以空间换时间。对齐原则也不例外,以耗费空间为代价,来加快寻址速度。

​ 至于原理:如果一个结构的最大成员字长为w,那么系统会假设在这种体系结构上字长为w的数据使用最频繁,优先提高对w位数据操作。所有的数据访问都以w位对齐,这样需要传输的地址位减少,寻址自然就可以加快。

​ 那么我们可以自己设定对齐规则吗?在规定的范围内是可以的,例如:

​ 在文件开头加 #pragma pack(1) //不对齐

​ #pragma pack(2) //支持1,2对齐

​ #pragma pack(4) //支持1,2,4对齐

​ #pragma pack(8) //支持1,2,4,8对齐(默认)

​ 也就是说pack是多少,结构体中的成员它的初始位置最多是多少的倍数

​ 嗯嗯,就酱紫~

转载请注明出处!!!

​ 如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢!

猜你喜欢

转载自blog.csdn.net/Ivan_zcy/article/details/82931336