对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。...再看数据结构B的自身对齐值为其变量中最大对齐值(这里是b)所以就是4,所以结构体的有效对齐值也是4。根据结构体圆整的要求, 0x0009到0x0000=10字节,(10+2)%4=0。...故B从0x0000到0x000B 共有12个字节,sizeof(struct B)=12; 同理,分析上面例子C: #progma pack (2) /*指定按2字节对齐*/ struct...又C的自身对齐值为4,所以 C的有效对齐值为2。又8%2=0,C只占用0x0000到0x0007的八个字节。所以sizeof(struct C)=8....2 Linux32位系统下gcc编译器默认对齐为4字节 3 在64位系统#pragma pack(4)的情况下,a1->c的地址按4字节对齐而不是按8字节(long在64位下为8字节长),会不会影响
结构体字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题。...为了使CPU存取的速度最快(这同CPU取数操作有关),c++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。...这样做可能会浪费一些内存,但在理论上CPU速度快了。 内存对齐的原因: 1)某些平台只能在特定的地址处访问特定类型的数据; 2)提高存取数据的速度。...(32)/GCC下如果该类型变量的长度没有超过CPU的字长, 则以该类型变量的长度作为自身对齐参数,如果该类型变量的长度超过CPU字长,则自身对齐参数为CPU字长,而32位系统其CPU字长是4,所以 linux...CPU的优化规则大致原则是这样的:对于n字节的元素(n=2,4,8,...),它的首地址能被n整除,才能获得最好的性能。
---- 准则 其实字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则: 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍...结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。 字节对齐的原因 各个硬件平台对存储空间的处理上有很大的不同。...比如有些架构的CPU在访问 一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对 数据存放进行对齐,会在存取效率上带来损失...例子4 若在程序中使用了#pragma pack(n)命令强制以n字节对齐时,默认情况下n为8. 则比较n和结构体中最长数据类型所占的字节大小,取两者中小的一个作为对齐标准。...S1 s1; double b; int c; }S5; 则sizeof(S5)=24.因为强制以4字节对齐,而S5中最长数据类型为double,占8字节,因此以4字节对齐。
(32)/GCC下如果该类型变量的长度没有超过CPU的字长,则以该类型变量的长度作为自身对齐参数,如果该类型变量的长度超过CPU字长,则自身对齐参数为CPU字长,而32位系统其CPU字长是4,所以linux...using namespace std; //#pragma pack(4) //设置4字节对齐 //#pragma pack() //取消4字节对齐 typedef struct...(n)默认值为8,则最终b的对齐参数为4,接下来的地址相对于结构体的起始地址的偏移量为1,1不能够整除4,所以需要在a后面填充3字节使得偏移量达到4,然后再为b分配4字节的空间; 对于变量c,它的自身对齐参数为...3字节达到4,为其分配8字节的空间; 对于变量b,它的自身对齐参数为8,#pragma pack(n)的默认值为8,则b的最终对齐参数为8,接下来的地址相对于结构体起始地址的偏移量为12,不能被8整除...,所以需要在s1后面填充4字节达到16,再为b分配8字节的空间; 对于变量c,它的自身对齐参数为4,#pragma pack(n)的默认值为8,则c的最终对齐参数为4,接下来相对于结构体其实地址的偏移量为
uint32_t a; char* b[0]; }; #pragma pack() sizeof(X)值为8,因为alignof(char*)和pack(8)最小值为8,故按8字节对齐...uint32_t a; char* b[0]; }; #pragma pack() sizeof(X)值为8,因为alignof(char*)和pack(4)最小值为4,故按4字节对齐...#pragma pack(1) struct X { uint32_t a; char* b[0]; }; #pragma pack() 按1字节对齐时,sizeof...(X)值为8,因为alignof(char*)和pack(1)最小值为4,故按1字节对齐。
{ double a;//8个字节 char b;//1个字节 float c;//4个字节 }DataType_8; #pragma pack(pop) //4字节对齐方式...{ double a;//8个字节 char b;//1个字节 float c;//4个字节 }DataType_2; #pragma pack(pop) //1字节对齐方式...相关概念 字节对齐: 现代计算机中,内存空间按照字节划分,理论上可以从任何起始地址访问任意类型的变量。...字节对齐的问题主要就是针对结构体。...引用一些博客博文说明 四个重要的基本概念: 数据类型自身的对齐值:char型数据自身对齐值为1字节,short型数据为2字节,int/float型为4字节,double型为8字节。
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。...再看数据结构B的自身对齐值为其变量中最大对齐值(这里是b)所以就是4,所以结构体的有效对齐值也是4。根据结构体圆整的要求, 0x0009到0x0000=10字节,(10+2)%4=0。...故B从0x0000到0x000B 共有12个字节,sizeof(struct B)=12; 同理,分析上面例子C: #pragma pack (2) /*指定按2字节对齐*/ struct C {...又C的自身对齐值为4,所以 C的有效对齐值为2。又8%2=0,C只占用0x0000到0x0007的八个字节。所以sizeof(struct C)=8....有 了以上的解释,相信你对C语言的字节对齐概念应该有了清楚的认识了吧。
S_local_capacity + 1]; size_type _M_allocated_capacity; }; }; 其中size_type的等价于size_t,64位机器上是8字节...,指针也是8字节.因此,上述我们可以知道内存结构为 8字节内存指针 8字节字符串长度 匿名的enum,并没有用一个枚举去声明一个名,不占内存. 16字节联合体 故string内部按8字节对齐,共占32字节大小.... 2.解析答案 现在回到上面那个问题上: 结构体A的内部结构通过上述的string,我们知道如下: 4字节int 8字节long 32字节string 而32字节又可以被展开为: 8 8 16 根据...string我们知道是8字节对齐,据此得出A为8字节对齐. int+long为12,需要填补到8的倍数边界,故为16,而string为32,不用变,因此最后为16+32=48.
有读者对字节对齐还有些疑问,这里分享一篇旧文。 字节对齐是我们初学C语言就会接触到的一个概念,但是到底什么是字节对齐?对齐准则又是什么?为什么要字节对齐呢?字节对齐对我们编程有什么启示?...那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。 对齐准则是什么 总的来说,字节对齐有以下准则: 结构体变量的首地址能够被其对齐字节数大小所整除。...为什么要字节对齐 无论数据是否对齐,大多数计算机还是能够正确工作,而且从前面可以看到,结构体test本来只需要11字节的空间,最后却占用了16字节,很明显浪费了空间,那么为什么还要进行字节对齐呢...实际编程中的考虑 实际上,字节对齐的细节都由编译器来完成,我们不需要特意进行字节的对齐,但并不意味着我们不需要关注字节对齐的问题。...1字节对齐 自己对结构进行字节填充 我们可以使用伪指令#pragma pack(n)(n为字节对齐数)来使得结构间一字节对齐。
2.为什么要有字节对齐 首先普及一点小知识,cpu一次能读取多少内存要看数据总线是多少位,如果是16位,则一次只能读取2个字节,如果是32位,则可以读取4个字节,并且cpu不能跨内存区间访问。...这四个字节,那么cpu如果想从内存中读取变量b,首先要从变量b的开始地址0x00000002读到0x0000004,然后再读取一次0x00000005这个字节,相当于读一个int,cpu从内存读取了两次...而如果进行字节对齐的话,变量a还是占用了0x00000001这一个字节,而变量b则是占用了0x00000005~0x00000008这四个字节,那么cpu要读取变量b的话,就直接一次性从0x00000005...所以说,字节对齐的根本原因其实在于cpu读取内存的效率问题,对齐以后,cpu读取内存的效率会更快。...3.手动设置对齐 什么情况下需要手动设置对齐: 设计不同CPU下的通信协议,比如两台服务器之间进行网络通信,共用一个结构体时,需要手动设置对齐规则,确保两边结构体长度一直; 编写硬件驱动程序时寄存器的结构
在二进制写文件时,可以用 模块将数据捆绑成结构体转化成字节流,为了方便与 交互,避免 在读取二进制字节流时因为 的字节对齐问题而造成不必要的麻烦, 的 模块默认按照...的字节对齐方式进行对齐。...('iq') 16 你没有看错,这里竟然字节对齐了,变成了 字节。...这波操作骚气啊……用 反复测试了两种写法,结果均为 字节。 不知道该怎么喷 ,最后图个省事儿,弄成了 ,妈妈再也不用担心字节对齐的问题了。...对了,如果有哪位大佬的编译器的确是不一样的字节对齐结果,麻烦告知用的是什么编译器,让我避开他……
为什么要字节对齐 简单的说来就是为了提高cpu的性能,或者说是为了提高程序运行的效率。当然,在其背后更有简化cpu设计的功效。...因此,我们写的c程序为了获得更高的运行效率就必须最大限度的满足cpu对于字节对齐的要求,编译器在其中起着至关重要的作用。...2字节对齐。...现在,我们开始分析采用字节对齐和不采用字节对齐时,cpu 对于内存的访问次数有何不同。...回到图1,先看看采用字节对齐时的情况,从图中可以看出,当cpu需要分别访问a变量和b变量时,无论如何都只需要分别进行一次内存存取,图中的花括号表示一次 内存存取操作。
这不,一个由字节对齐导致的挂死问题就出来了。...字节对齐和64位 关于字节对齐,可参考《理一理字节对齐的那些事》,而之前也分享过另一个切64位之后出现的问题,有兴趣的可以查看《记64位地址截断引发的挂死问题》。...,而cJSON的头文件也在其中,那么就会导致里面的cJSON结构体按照1字节对齐,最终其结构体大小为56个字节,而已经编译好的cjson库可并非如此,因此对于64位程序,它还是按照8字节对齐,结构体大小为...64字节,而对于32位程序,按照4字节和1字节对齐,都是36字节,因此也不会有问题。...思考 什么情况下需要1字节对齐呢? 附录 本文完整代码可点击阅读原文或者访问 http://www.yanbinghu.com/2019/08/04/21364.html 附录部分。
作者:李云 摘要 字节对齐(alignment)是CPU在性能方面所面临的一个非常重要的问题。...有些处理器能自动处理不对齐数据的访问(对字节对齐要求不严格),但是,有些处理器却无法处理(对字节对齐要求很严格)。...对于c程序员,大部分情况下我们并不考虑字节对齐问题,这并不是说我们并不需要考虑,而是因为碰到这种问题的情况很少。一方面要在特定的处理器上,而另一方面和我们写的程序也有关系。...因此,结果给我们的感觉是”字节对齐与我无关”。 本文通过一小段代码通过在不同处理器上的运行结果引出对字节对齐问题的关注,同时进行原因分析。 1....这其实是一个cpu对齐所引发的问题,下面我们通过对字节对齐问题的分析来探究其背后的原理。后面的分析我们全部针对运行在32位SPARC处理器上的Solaris操作系统进行的。
前言 字节对齐是我们初学C语言就会接触到的一个概念,但是到底什么是字节对齐?对齐准则又是什么?为什么要字节对齐呢?字节对齐对我们编程有什么启示?本文将简单理一理字节对齐的那些事。...那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。 对齐准则是什么 总的来说,字节对齐有以下准则: 结构体变量的首地址能够被其最大基本类型成员字节数大小所整除。...为什么要字节对齐 无论数据是否对齐,大多数计算机还是能够正确工作,而且从前面可以看到,结构体test本来只需要11字节的空间,最后却占用了16字节,很明显浪费了空间,那么为什么还要进行字节对齐呢...实际编程中的考虑 实际上,字节对齐的细节都由编译器来完成,我们不需要特意进行字节的对齐,但并不意味着我们不需要关注字节对齐的问题。...1字节对齐 自己对结构进行字节填充 我们可以使用伪指令#pragma pack(n)(n为字节对齐数)来使得结构间一字节对齐。
应该是13个字节, 为什么会有别的答案. 甚至没有#pragma pack (v)的情况下都是16. 原因就在于字节对齐....关于字节对齐为啥存在, 简单来说, 就是数据都是一块一块读的, 不是一个一个....而64位默认是8字节对齐. 然后你会说, 就这? 类大小 那么下面这个呢?...如果4字节对齐就是60. 注意, 这里C, D都有虚指针, 被E继承. 如果变化下, 改成虚继承....其实2个虚指针+B的变量+C的变量, 16+13+4=33, 8字节对齐, 40.
结构体字节对齐 结构体的空间大小: 结构体为了保证CPU的访问效率,默认采用内存对齐机制 对齐标准为结构体中基础数据类型的成员最大值 对齐标准和成员申明顺序有关 #include #...以上面案例分析:CPU可以在一个周期中直接取出age,因为age正好占4个字节,但是如果想取出name,占15个字节,cpu仍需要4个的来取,所以仍然需要取16个。...以上面图片分析,假如不采取内存对齐规则:CPU从上往下进行读取,上面的矩形代表age的4个字节,中间的椭圆代表name的15个字节,下面的矩形代其他数据占用的内存(假设占4个字节)。...根据CPU读取内存的周期,我知道CPU需要读取name时要去读16个字节,也就是会读取到下面的其他数据的一个字节,但是使用时只截取前15个字节,可以正常使用,此时cpu指向下面的其他数据的那一个一个字节所在的地址处...,提出了一个概念:字节对齐。
uint8_t定义变量地址要1字节对齐。 uint16_t定义变量地址要2字节对齐。 uint32_t定义变量地址要4字节对齐。 uint64_t定义变量地址要8字节对齐。...,a单字节对齐,b是两字节对齐,而c要是4字节对齐,从出现b定义完毕后空出来1个字节未被使用。...d是8字节对齐,这样就是16字节。...,b占用2字节对齐,c需要4字节对齐,这样就空出来2两个字节未使用,d占用8字节,最后一个a占用了8字节。...比如使用SDIO DMA从SD卡读取数据,我们就可以设置源地址依然是4字节对齐(外设访问要4字节对齐),而目的地址设置为字节对齐,就可以方便的解决4字节对齐问题。
本文就从cpu读取内存的角度来谈谈内存对齐的原理。 01 结构体字段对齐示例 我们先从一个示例开始。T1结构体,共有3个字段,类型分别为int8,int64,int32。...这个长度也称为CPU的字长(注意这里和字节的区别,字节是固定的8位,而字长随着CPU的规格变化,32位的字长是4字节,64位的字长是8字节)。...所以,为了能让CPU可以更快的存取到各个字段,Go编译器会帮你把struct结构体做数据的对齐。...所谓的数据对齐,是指内存地址是所存储数据大小(按字节为单位)的整数倍,以便CPU可以一次将该数据从内存中读取出来。 编译器通过在T1结构体的各个字段之间填充一些空白已达到对齐的目的。...以T1结构体为例,实际存储数据的只有13字节,但实际用了24字节,浪费了将近一半,那有没有什么办法既可以做到内存对齐提高CPU读取效率又能减少内存浪费的吗? 答案就是调整struct字段的顺序。
闲话少说,让我们来看看CPU在读写内存时底层究竟发生了什么。 ? 谁来告诉CPU读写内存 我们第一个要搞清楚的问题是:谁来告诉CPU去读写内存? 答案很明显,是程序员,更具体的是编译器。...在这种速度差异下,CPU执行一条涉及内存读写指令时需要等“很长一段时间“数据才能”缓缓的“从内存读取到CPU中,在这种情况你还认为CPU应该直接读写内存吗?...多级cache 现代CPU为了增加CPU读写内存性能,已经在CPU和内存之间增加了多级cache,典型的有三级,L1、L2和L3,CPU读内存时首先从L1 cache找起,能找到直接返回,否则就要在L2...CPU开始拥有多个核心后不但苦逼了软件工程师,硬件工程师也不能幸免。 前文提到过,为提高CPU 访存性能,CPU和内存之间会有一个层cache,但当CPU有多个核心后新的问题来了: ?...天真的CPU CPU真的是很傻很天真的存在。 上一节讲的操作系统施加的障眼法把CPU也蒙在鼓里。
领取专属 10元无门槛券
手把手带您无忧上云