结构体在C语言中还是非常重要的,结构体的内存对齐规律也应该是结构体这块内容中最重要的知识点了(但是要掌握也并不是很难哦)。因此要掌握结构体就必须将内存对齐这个规律牢记于心!
我认为要学习这块的知识,首先要牢记内存对齐的这几条规律:
1.第一个成员总是在(距结构体变量起始位置处)偏移量为0的地址处;
2.其他成员的偏移量在对齐数的整数倍的地址处;
对齐数:取该成员的内存大小与编译器默认对齐数的较小值。
在这里要提醒一下:windows(vs)中默认对齐数为8字节,linux中默认对齐数为4字节
3.结构体的总大小为最大对齐数(每个成员存放时都有对齐数)的整数倍
4.如果存在结构体的嵌套,嵌套结构体对齐到自己的最大对齐数的整数倍处,则结构体的总大小为包括嵌套结构体成员在内的最大对齐数的整数倍
当然以上的规律让我们看起来也是比较头大,无从下手,不好理解。因此呢,要结合上述规律,再根据某个具体的结构体,参照以上规律,理解并画出结构体成员在内存中的布局(一定要亲自画一画哦,这样你才会有更深的理解,方便记忆)。
下面是我在学习的过程中,根据理解认认真真的画出来的结构体成员在内存中的分布。希望能对不是很懂的朋友们有所帮助,也是方便自己以后的复习。
a.<无嵌套结构>
b.<存在嵌套结构体时>
这里有个小的知识点还得牢记:默认对齐数。上面已经提到常用的两个编译器中的默认对齐数,那么能不能修改编译器的默认对齐数呢?(当然是可以的,我第一次遇到时完全不知道这是啥)
#pragma pack(n) //将编译器的默认对齐数修改为n,(此处n只能是1、2、4、8、16...(2^i))
#pragma pack //取消默认对齐数的修改
除此之外,也可在编译器中直接修改
刚开始学习C语言朋友们接触到内存对齐时,都应该想过这个东西到底有啥用啊?
我了解到,存在内存对齐的原因有一下两点:
1、 平台原因(移植原因)
不是所有的硬件平台都能访问任意地址上的数据;
2、 性能原因
数据结构(尤其是栈)应该尽可能的在自然边界上对齐;(32位 处理器每次访问4个字节)
为了访问未对齐的内存,处理器需要做两次的内存访问;而对齐的内存只需要访问一次。(提高效率)
综上所述:结构体的内存对齐是拿空间换取时间的做法
因此,在设计结构体时,要让占用空间小的成员尽量集中在一起(节省了空间)
我觉得要学好结构体这块的知识,内存对齐以及其原因是一定要掌握滴~
所以朋友们我们还是要加油鸭!