怎么做淘宝返利网站,wordpress文字目录,阿里巴巴网站建设的不足之处,网站设计思路怎么写结构体内存对齐与结构体类型的大小
运行这样一段代码 我们想要计算这两个结构体类型的大小#xff0c;而这个结构体类型里面成员变量有一个int类型和两个char类型#xff0c;大小加起来应该是六个字节#xff0c;但是我们打印出来发现#xff0c;结果居然是12和8#xff…结构体内存对齐与结构体类型的大小
运行这样一段代码 我们想要计算这两个结构体类型的大小而这个结构体类型里面成员变量有一个int类型和两个char类型大小加起来应该是六个字节但是我们打印出来发现结果居然是12和8不仅不是6甚至都两次结果都不一样大这是为什么呢
通过offsetof计算出struct s1各个成员变量离起始地址的偏移量分别是0,4,8,offsetof是一个宏具体用法这里就不展开讲了于是我们可以画出struct s1的成员变量在内存中的分布 那也就是占了九个字节为什么struct s1的大小会是12呢
这就涉及到了内存对齐
首先得掌握结构体的对齐规则
1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字对齐数的整数倍的地址处。
对齐数 编译器默认的一个对齐数与该成员大小的较小值。VS中默认的值为8gcc环境没有对齐数
3. 结构体总大小为最大对齐数每个成员变量都有一个对齐数的整数倍。
4. 如果嵌套了结构体的情况嵌套的结构体对齐到自己的最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数含嵌套结构体的对齐数的整数倍。
知道了这些规则之后再来看上面的struct s1在内存中为什么这样存储struct s1的第一个成员变量是char类型的因此对齐数是1因此第一个成员变量就放在了偏移量为零的单元第二个成员变量i是int类型的对齐数是4应该放偏移量是在4的整数倍的单元处因此从4开始放四个字节浪费了三个字节单元第三个成员变量也是char类型的对齐数是1因此接着放一个字节如图所示 一共占用了9个字节但是根据第三条规则结构体类型的大小必须是所有成员变量中最大对齐数的整数倍struct s1的成员变量最大对齐数是49不是4的倍数此时离着4的倍数最近的字节数是12因此struct s1的大小是12个字节。
同样的再来看struct s2 他的第一个成员变量是int类型的从偏移量为零的地址处开始存放放了四个字节第二个成员变量是char类型的对齐数是1直接接着放就行因为任何数都是1的整数倍。第三个成员变量也是char类型的对齐数是1接着放一个字节发现一共用了6个字节最大对齐数是4,6不是4的倍数离着最近的一个4的倍数是8因此struct s2的大小是8
结构体嵌套问题 struct s4类型的第一个成员变量是char类型的对齐数是1直接在偏移量为0的地址处开始存放第二个成员变量是struct s3类型的他的成员变量最大对齐数是8因此他要对齐到偏移量为8的整数倍的位置离着最近的就是从偏移量为8的位置开始存放存放多少个字节那就要看struct s3类型占多少个字节。
我们假设又有一块空间存放着struct s3
struct s3的第一个成员变量是double类型对齐数是8从偏移量为0的地址处开始存放存放了8个字节存到了偏移量为7的位置第二个成员变量是char类型的对齐数是1接着存一个字节存到了偏移量为8的位置第三个成员变量是int类型的对齐数是4但是接下来要存的单元偏移量是9不是4的整数倍因此要从偏移量为12的位置开始存放四个字节到了偏移量为15的位置。又因为struct s3的成员变量最大对齐数是8因此struct s3所占的字节大小就是离15最近的8的整数倍也就是16.
再回到struct s4的存储从偏移量为8的单元开始放16个字节到了偏移量为23的位置struct s4的第三个成员变量是double类型的对齐数是8而接下来要存放的位置偏移量是24恰好是8的整数倍因此接着存放8个字节单元到了偏移量为31的单元处。共计占用了32个字节。所有成员变量的最大对齐数是8,而32恰好是8的整数倍因此struct s4的大小是32个字节
为什么存在内存对齐
1. 平台原因(移植原因)不是所有的硬件平台都能访问任意地址上的任意数据的某些硬件平台只能在某些地址处取某些特定类型的数据否则抛出硬件异常。
2. 性能原因数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于为了访问未对齐的内存处理器需要作两次内存访问而对齐的内存访问仅需要一次访问。
总体来说结构体的内存对齐是拿空间来换取时间的做法。