当前位置:首页 > 内存 > 正文

内存对齐问题

  • 内存
  • 2024-06-06 10:15:49
  • 2970

一、结构体内存对齐结构内存对齐
1结构对齐的三大原则
1数据成员对齐规则:结构(或联合)数据,第一个数据集的成员设置为偏移0,并且任何未来数据成员存储的起始位置必须是该成员的大小或该成员的子成员的大小(只要该成员具有子成员,例如字符串、结构体等)(例如,如果int为4个字节,则必须从4的整数倍地址开始存储)
2结构体作为成员:如果结构体中存在某些结构体成员,则结构体的成员必须从内部元素最大尺寸的整数倍的地址开始存储(structa包含structb,b包含char、int、double等元素,则必须存储b从8的整数倍开始)
3收尾工作:结构体的总大小,即大小的结果,必须是其最大内部倍数的整数倍。成员,任何不足都必须填补。
首先我们看一下不同操作系统上每种数据类型占用的位数
2.强制执行内存对齐规则。>图.输出是24,为什么是24?
a是double类型,占用8个字节,并且因为是第一个成员,所以初始值对应的是偏移量为0的位置。又因为占用8个字节,所以a对应的是偏移量为8的地址空间
b是char类型,占用1个字节,与1的整数倍对齐,即跟随一个地址空间。
c是int类型,占用4个字节,对齐到4的整数倍,对齐数为12,地址空间偏移量为4
d为Short类型,占用2个字节,对齐为2的整数倍,盘区数为16,偏移量为2个地址空间
结构体的总大小必须是其最大内部成员的整数倍,且struct1中最大的成员是double类型,因此该结构的总大小是8的整数倍。它当前占用17个字节,因此总大小必须为24个字节。/>
我们看一下下面的结果。
输出结果为16。
如图,a不变
b为int类型,占用4字节,对齐以4的整数倍对齐,对齐数为8,偏移量为4地址空间
c为char类型,占用1字节,以1的整数倍对齐,即下一个地址空间。
d为short类型,占用2字节,对齐为2的整数倍,对齐数为14,偏移量为2的地址空间
并且由于内存对齐的原理,所以该结构体的总大小为16字节
那么该结构体如果嵌套还可以构建吗,那么内存应该如何计算呢?
这里的产量是多少?我们来计算一下
如图,a不变
b是int类型,占用4个字节,对齐到4的整数倍,extent数为8、大小为4的偏移地址空间
C为char类型,占用1字节,对齐到1的整数倍,即下一个地址空间。
d为short类型,占用2字节,对齐为2的整数倍,对齐数为14,地址空间偏移量为2
e为int类型,占用4个字节,对齐为4的整数倍,对齐数为16,偏移量为4地址空间
已知struct1占用24个字节,double占用第8节话说,如果你不知道为什么,请查一下。
结构体作为成员:如果有结构体成员分配给结构体,则结构体成员必须从最大内部元素大小的整数倍的地址开始存储(structa包含structb,b有char、int、double等元素,那么b必须以8的整数倍存储)
所以struct1必须以8的整数倍存储
那么struct1占用24字节,以8的整数倍对齐,对齐号24,偏移量24地址空间
所以结构体总大小为48字节
3为什么需要内存对齐?
(1)性能提升
从内存使用的角度来看,某些情况下,对齐后内存分配的成本相比不均匀会增加?
数据结构(尤其是堆栈)必须尽可能在自然边界上对齐,以访问非对齐内存,处理器必须进行两次对齐内存访问。最重要的是提高内存系统的性能。
(2)跨平台
有些硬件平台无法访问任何地址的任何数据,只能处理特定类型的数据,否则会导致硬件层面的错误。。
某些CPU(例如基于Alpha、IA-64、MIPS和SuperH系统的CPU)拒绝读取未链接的数据。当程序要求这些CPU读取不相关的数据时,CPU将进入异常处理状态并通知程序无法继续执行。
例如,在ARM、MIPS和SH硬件平台上,当操作系统需要访问未绑定的数据时,默认情况下它会引发应用程序的硬件异常。因此,如果编译器不进行内存对齐,跨平台开发就会变得困难。


二、内存对齐详解1.什么是内存对齐
假设我们声明两个变量:
2.结构体内存对齐规则
结构体及其成员在结构体中占用的内存与结构体中声明的顺序有关,其成员的内存对齐规则如下:
(1)每个成员根据其对齐字节数和PPB(特定对齐)来划分。字节数,32位机默认为4)将字节数最小的两者对齐,以减少长度。
(2)复杂类型(例如结构体)的默认对齐方式是其最长成员的对齐方式,因此当成员是复杂类型时可以减少长度。
(3)结构体的对齐长度应该是成员之间最大对齐参数(PPB)的整数倍,这样可以保证处理时每个元素都对齐到边界数组。
(4)计算结构体内存大小时,必须包含各个成员的偏移地址,则其长度=最后一个成员的偏移地址+最后一个成员编号的长度+最后设置成员参数(考虑PPB)。
3.案例说明:
———————————————
最终结果为:8
//>
4.需要注意的问题
(1)字节对齐取决于编译器;
(2)一定要注意PPB的大小,由pragampack(n)指定);
(3)应该是结构体占用的字节数能被PPB整除。
(4)公式总结:结构体的大小等于最后一个成员的偏移量加上其大小加上末尾的填充字节数,即:
sizeof(struct)=offset(lastitem)+sizeof(lastitem)+sizeof(Trailingpadding)
———————————————
原文链接:https://blog.网/SzMinglove/java/article/details/8143056