什么地方要用到对齐数的概念呢?
只要涉及到多个数据的内存的存储方面,一般是都要讲对齐这个概念的,但是在目前为止,对齐这个概念注意凸显在结构体中。因为数组中都是同种类型的数据,所以并不会浪费空间。但是结构体中存储的是不同类型的数据,难免会浪费一些空间。
C语言之内存对齐数_微风-CSDN博客_c语言内存对齐
问题一:为什仫要内存对齐?
我们知道的是计算机中最小的存储单位是字节(一个字节是八个比特位),当我们查找数据的时候可以一个字节一个字节的查找,但是这种查找方式存在缺陷:查找速度慢。如果不存在内存对齐,在实例三中,我们首先为结构体变量c分配一个字节,然后紧着我们为结构体变量c2分配一个字节,在最后我们为结构体整形变量i分配四个字节;如果我们一个字节一个字节查找元素的话,找c和c2当然很容易了,可是找i呢?我们知道内存为整形变量i分配了4个字节,我们要访问完整的i我们需要找到变量c2之后的四块存储空间,和我们刚开始定义的一样我们是一个字节一个字节找,此时指针需要移动三次才可以找到全部整形变量i的所有字节。是不是觉得很麻烦呢?如果有了内存对齐呢?我们可以四个字节四个字节的找,是不是就提高了我们查找的速率呢?那是肯定的啦!所谓的内存对齐就是牺牲了部分空间来换取效率的方法。
问题二:内存对齐有哪些规则?
1).结构体变量的首地址能够被其最宽基本类型成员的大小所整除,结构体的第一个成员永远放在零偏移处;
2).结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字符;
3). 结构体的总大小为结构体最宽基本类型成员大小和编译器缺省対界条件大小中比较小得那个值的整数倍,如有需要编译器会在最后一个成员之后加上填充字节;
4).在这里我们是可以修改默认对齐数的,一般我们用 #progma pack(n)这个语句来设置默认对齐数, 在这个我设置的默认对齐数是n,读者可根据自己的需要自行设置对齐数;用#progma pack()来取消设置对齐数, 换句话说就是我们可以自己修改内存中的默认对齐数;
通过上述几个规则大家是不是对内存对齐有了更深的理解呢?下面我就来画图理解上述三个类似的范例:
C语言之内存对齐数_微风-CSDN博客_c语言内存对齐
#pragma 这是个预处理指令,可以修改默认对齐数
这下面两个分别是改了默认对齐数和没有改的。
改完之后记得要还原。
补:
offsetof函数,返回值为偏移量
size_t offsetof(类型名,成员名)
返回值为相对于结构体头部的偏移量。