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

内存对齐原则(struct内存对齐规则)

  • 内存
  • 2024-05-08 00:06:56
  • 4359

一、linux下怎么设置内存对齐内存对齐有一些规则:
A.基本类型:所有基本类型都有相应的对齐参数。编译时,编译器会使用最小的全局对齐参数和当前类型的对齐参数。例如,编译时指定为8字节对齐(由#pragmapack(8)实现),但由于char变量的大小为1字节,所以最后仍然是1字节对齐。
B.复合类型:复合类型的对齐原则是在成员变量数据类型的最大字节数与编译时指定的对齐数之间取较小的字节数。如果没有使用#pragmapack等指定全局对齐数,则复合类型的对齐数为其成员变量数据类型的最大字节数。


二、关于sizeof()的问题这和内存对齐问题有关,一般情况下,我们在写程序的时候并不总是考虑内存对齐问题,因为它是由编译器自动完成的,但是要解决这个问题,我们确实需要仔细看看这个。问题,即。挺麻烦的,我简单的告诉你一下。。。
按理说数据在内存中应该是按顺序存储的,从第一个位置到最后一个位置,但事实并非如此,因为这样做会降低效率,CPU会读取数据基于块,所以如果数据对齐,则可以读取一次,但如果未对齐,则可以再读取一次,这样效率不高,因此必须进行对齐。。
要计算对齐数据占用的空间,首先要明确以下对齐值之间的区别:
1.//你可以将其理解为该类型变量占用的存储空间。例如,在标准C++中,如果一个int占用的空间为4,则该int的自对齐值为4。
2.指定对齐值:
编译时,可以向编译器指定一个对齐值。如果不指定该值,编译器将使用其自己的默认对齐值。,I使用的C++Builder指定的默认对齐值为4。
3.结构体或类的自关联值:
是其成员中自关联值最大的值。
4.数据成员、结构体、类的有效对齐值:
自身对齐值与指定对齐值中较小的一个。
计算时必须遵循以下原则:
首先假设数据成员的有效对齐值为N,那么到该成员存储的第一个x地址必须满足x%N=0。如果不等于0,则无法保存,必须撤消。
其次,结构体和类的大小,即sizeof之后的结果,必须是其中成员的最大对齐值。如果没有,则必须填写。
现在我们来计算一下你的问题:
i的类型是int,所以它自己的对齐值是4,并且表明对齐值默认是4(即默认对齐值系统对齐)value),所以i的有效对齐值为4,因此可以假设i是从内存中的0x00000位置开始存储的,因为0x00000%4=0,满足第一原则。
而i本身占用4个字节,所以i的存储空间为:0x00000到0x00003
而且j也是int类型,所以j的有效对齐值也是4,所以j可以从0x00004开始存储由于0x00004%4=0也满足第一条规则。
所以,j的存储空间为:0x00004到0x00007
剩余K个。k的自对齐值为1,指定的对齐值为4,因此有效对齐值为该对齐值中较小的一个。二、是1,所以k可以从0x00008开始存储,因为0x00008%1=0。所以k的存储空间为0x00008。
现在我们知道i、j、k的存储空间是从0x00000到0x00008,占用9个字节。第二个原则仍然需要遵循。
整个层X的大小必须是所有成员最大对齐值的整数倍,不足部分必须补足。成员的最大对齐值是4,但目前只占用9个字节,所以必须加上12才能满足条件,所以最终的sizeof结果是12。
按键确实很难。。。我找到了回到高中写论文的方法。。。


三、sizeof问题内存对齐问题。
C语言内存对齐的一般原则是成员变量存储的起始地址应该是成员变量大小的整数倍。
那么,sizeof(char)=1,sizeof(int)=4,sizeof(short)=2。
所以对于name1来说,str的起始地址是name1+0,x的起始地址是name1+2,num的起始地址是name1+4。计算到name1末尾,共有8个字节,其中3个字节没有存储数据。
name2也是如此,str:0num:4short:8,总共占用10个字节。不过,结构体本身的大小也是约定好的,只不过这个约定在编译器之间是不同的。,它必须是4的倍数(因此4到10最接近的倍数是12)。
冒号表示指定数据成员占用的大小(位)。那么s1的前三个成员都小于8字节,那么double就对齐到8字节,再加上自己的8字节。字节,有16个字节。(针对您的编译器)
关于s2,最多double需要16个字节(取决于您的编译器),由于最长的成员是8个字节,因此结构本身与8个字节对齐(有些编译器会对齐4个字节,或者8个字节取决于的编译器,但无论如何它似乎最多与8个字节对齐)。