字节对齐

C++ 字节对齐

折月煮酒 提交于 2019-12-23 03:52:00
1. 缘起 来自BBS上的面试题目,struct{int a; char b;}的大小是多少?答案是8。上网看了下,是字节对齐。 2. 字节对齐的基本规则 首先,每种类型的变量的默认对齐长度都是自己的变量长度,比如:char占一个字节,那么对齐长度就是一个字节,int占四个字节,对齐长度就是四个字节,double占八个字节,对齐长度就是8。int的对齐长度为4的实际意义是,int变量必须存储在四的倍数的地址上。 那么对于struct{char b; int a},其长度是8,因为b虽然只占用1个字节,但是a必须从4的倍数开始存储,因此b后面的3个字节都废掉了。因此一共需要8个字节才能把b和a存下来。 那么对于struct{int a; char b},其长度还是8!晕菜了!原因如下: 字节对齐的细节和编译器实现相关,但一般而言,满足三个准则: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除。 2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding); 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。 规则1是控制结构体变量的首地址的,与结构体变量的长度没关系。

C++内存对齐的理解

痞子三分冷 提交于 2019-12-21 11:02:51
程序编译器对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。 编译器中提供了 #pragma pack(n)来设定变量以n 字节对齐 方式。 n字节对齐就是说变量存放的起始地址的 偏移量 有两种情况: 第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式, 第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。 结构的总大小也有个约束条件,分下面两种情况: 如果n大于所有 成员变量 类型所占用的字节数,那么 结构的总大小必须为占用空间最大的变量占用的空间数的倍数 ; 否则必须为n的倍数。 重要的规则 1,复杂类型中各个成员按照它们被声明的顺序在 内存中顺序存 储,第一个成员的地址和整个类型的地址相同; 2, 每个成员分别对齐,即每个成员按 自己的方式对齐 ,并最小化长 规则就 是每个成员 按其类型的 对齐参数(通常是这个类型的大小) 和 指定对齐参数 中 较小的一个对齐(对齐指的是数据类型在内存中的起始的N倍的跨度) ; (指 复杂类型中成员类型 中自己的对齐方式,并不是结构体等整体的对齐方式) 3, 结构 、 联合 或者 类的数据成员 ,第一个放在偏移为0的地方;以后每个数据成员的对齐,按照#pragma

C语言字节对齐 __align(),__attribute((aligned (n))),#pragma pack(n)

江枫思渺然 提交于 2019-12-13 19:56:16
转载地址 : http://blog.csdn.net/21aspnet/article/details/6729724      https://www.cnblogs.com/ransn/p/5081198.html 例子:__align(),__attribute((aligned (n))),#pragma pack(n) # include <stdio.h> main ( ) { struct A { int a ; char b ; short c ; } ; struct B { char b ; int a ; short c ; } ; # pragma pack (2) /*指定按2字节对齐*/ struct C { char b ; int a ; short c ; } ; # pragma pack () /*取消指定对齐,恢复缺省对齐*/ # pragma pack (1) /*指定按1字节对齐*/ struct D { char b ; int a ; short c ; } ; # pragma pack () /*取消指定对齐,恢复缺省对齐*/ int s1 = sizeof ( struct A ) ; int s2 = sizeof ( struct B ) ; int s3 = sizeof ( struct C ) ; int s4 =

C/C++内存对齐详解

旧时模样 提交于 2019-12-13 15:03:23
1、什么是内存对齐 还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占4+1=5byte;但是实际上,通过运行程序得到的结果是8 byte,这就是内存对齐所导致的。 //32位系统 #include<stdio.h> struct{ int x; char y; }s; int main() { printf("%d\n",sizeof(s); // 输出8 return 0; } 现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。 2、为什么要进行内存对齐 尽管内存是以字节为单位,但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存,我们将上述这些存取单位称为内存存取粒度. 现在考虑4字节存取粒度的处理器取int类型变量(32位系统),该处理器只能从地址为4的倍数的内存开始读取数据。 假如没有内存对齐机制,数据可以任意存放,现在一个int变量存放在从地址1开始的联系四个字节地址中,该处理器去取数据时

虹软人脸识别3.0 - 图像数据结构介绍(Android)

谁说胖子不能爱 提交于 2019-12-11 21:00:35
从虹软开放了2.0版本SDK以来,由于具有免费、离线使用的特点,我们公司在人脸识别门禁应用中使用了虹软SDK,识别效果还不错,因此比较关注虹软SDK的官方动态。近期上线了ArcFace 3.0 SDK版本,确实做了比较大的更新。首先本篇介绍一下关于Android平台算法的更新内容,下一篇将针对Windows平台的算法更新展开介绍。 特征比对支持比对模型选择,有 生活照比对模型 和 人证比对模型 识别率、防***效果显著提升 特征值更新,升级后人脸库需重新注册 Android平台新增64位的SDK 图像处理工具类 人脸检测同时支持全角度及单一角度 新增了一种图像数据传入方式 在实际开发过程中使用新的图像数据结构具有一定的难度,本文将从以下几点对该图像数据结构及使用方式进行详细介绍 SDK接口变动 ArcSoftImageInfo类解析 SDK相关代码解析 步长的作用 将Camera2回传的Image转换为ArcSoftImageInfo 一、SDK接口变动 在接入3.0版SDK时,发现 FaceEngine 类中的 detectFaces 、 process 、 extractFaceFeature 等传入图像数据的函数都有重载函数,重载函数的接口均使用 ArcSoftImageInfo 对象作为入参的图像数据,以人脸检测为例,具体接口如下: 原始接口: public int

c内存对齐--影响php变量占用的内存

只愿长相守 提交于 2019-12-10 13:39:26
当在C中定义了一个结构类型时,它的大小是否等于各字段(field)大小之和?编译器将如何在内存中放置这些字段?ANSI C对结构体的内存布局有什么要求?而我们的程序又能否依赖这种布局?这些问题或许对不少朋友来说还有点模糊,那么本文就试着探究它们背后的秘密。 首先,至少有一点可以肯定,那就是ANSI C保证结构体中各字段在内存中出现的位置是随它们的声明顺序依次递增的,并且第一个字段的首地址等于整个结构体实例的首地址。比如有这样一个结构体: struct vector{ int x,y,z; } s; int *p,*q,*r; struct vector *ps; p = &s.x; q = &s.y; r = &s.z; ps = &s; assert(p < q); assert(p < r); assert(q < r); assert((int*)ps == p); // 上述断言一定不会失败 这时,有朋友可能会问:"标准是否规定相邻字段在内存中也相邻?"。 唔,对不起,ANSI C没有做出保证,你的程序在任何时候都不应该依赖这个假设。那这是否意味着我们永远无法勾勒出一幅更清晰更精确的结构体内存布局图?哦,当然不是。不过先让我们从这个问题中暂时抽身,关注一下另一个重要问题————内存对齐。 许多实际的计算机系统对基本类型数据在内存中存放的位置有限制

内存对齐

…衆ロ難τιáo~ 提交于 2019-12-08 11:10:30
首先在C语言中, 结构体占用的是一片连续的内存空间 对齐原因 大部分的参考资料都是如是说的:   1、 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。   2、 性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。 以前对于内存对齐的计算理解错了,今天看见一个视频幡然醒悟。 以下面的结构体为例: struct stu { char *p;  //4 char arr[2];  //2  → 4+2+2(补)=8 int c;  //4 short d;  //2  → 4+2+2(补)=8 double f;  //8 long g;  //4  → 4+4(下面 float h[2] 中取一个刚好可以凑足 8 个字节)=8 float h[2];  //  4(上面拿走了一个)+4(补)=8 }stu; 内存对齐规则 :以结构体中占用字节数最大的修饰变量的关键字为基准进行对齐。 在 stu 中(32位操作系统):首先占用内存最大的关键字为 double 占 8 个字节。   以此为基准对齐,从头开始看。指针 p 占四个字节,arr 占 1*2 = 2个字节,共 6 个字节,不足 8 位

【内存字节】深入理解sizeof占位内存

核能气质少年 提交于 2019-12-06 20:28:17
###运行代码 让计算机告诉你数据类型站内存情况 //32位系统,地址长度是32位(bit),也就是4Byte 64位系统,地址长度是64位(bit),也就是8Byte //注意 1byte = 8 bit;sizeof byte #import <Foundation/Foundation.h> int main(int argc, char *argv[]) { @autoreleasepool { char a[] = "go swift"; //自动为末尾加上'/0',注意空格也要占字节 char b[14] = "go swift"; char *c = a; char *d = "01234"; int16_t t16; int32_t t32; int64_t t64; NSLog(@"%ld", sizeof(a)); NSLog(@"%ld", sizeof(b)); NSLog(@"%ld", sizeof(c)); NSLog(@"%ld", sizeof(d)); //d是指向字符串常量的字符指针 NSLog(@"%ld", sizeof(*d)); //*d是第一个字符 (所占大小由数据类型决定) NSLog(@"int type: %ld,%ld,%ld,%ld", sizeof(t16),sizeof(t32),sizeof(t64),sizeof(

glPixelStorei 详解 包括像素传输

爱⌒轻易说出口 提交于 2019-12-06 12:04:23
3.glPixelStore 像glPixelStorei(GL_PACK_ALIGNMENT, 1)这样的调用,通常会用于像素传输(PACK/UNPACK)的场合。尤其是导入纹理(glTexImage2D)的时候: C++代码 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(,,,, &pixelData); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 很明显地,它是在改变某个状态量,然后再Restore回来。——为什么是状态?你难道8知道OpenGL就是以状态机不?——什么状态?其实名字已经很直白了,glPixelStore这组函数要改变的是像素的存储格式。 涉及到像素在CPU和GPU上的传输,那就有个 存储格式 的概念。在本地内存中端像素集合是什么格式?传输到GPU时又是什么格式?格式会是一样么?在glTexImage2D这个函数中,包含两个关于颜色格式的参数,一个是纹理(GPU端,也可以说server端)的,一个是像素数据(程序内存上,也就是client端)的,两者是不一定一样的,哪怕一样也无法代表GPU会像内存那样去存储。或者想象一下,从一张硬盘上的图片提取到内存的像素数据,上传给GPU成为一张纹理,这个“纹理”还会是原来的那种RGBARGBA的一个序列完事么?显然不是的

【Linux】C字节对齐

大兔子大兔子 提交于 2019-12-05 22:18:42
什么是对齐,以及为什么要对齐 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 对齐的作用和原因 各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为 32 位系统)存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。 对齐的实现 通常,我们写程序的时候,不需要考虑对齐问题。编译器会替我们选择适合目标平台的对齐策略。当然,我们也可以通过给编译器传递预编译指令而改变对指定数据的对齐方法。 但是,正因为我们一般不需要关心这个问题,所以当编辑器对数据存放做了对齐,而我们不了解的话,常常会对一些问题感到迷惑。最常见的就是struct数据结构的sizeof结果,出乎意料。为此,我们需要对对齐算法所了解。 对齐的算法