精华内容
下载资源
问答
  • 作者:守望,Linux应用开发者,目前在公众号【编程珠玑】分享Linux/C/C++/数据结构与算法/工具等原创技术文章和学习资源。...什么是字节对齐计算机中内存大小基本单位是字节(byte),理论上来讲,可以从任...

    作者:守望,Linux应用开发者,目前在公众号【编程珠玑】 分享Linux/C/C++/数据结构与算法/工具等原创技术文章和学习资源。

    前言

    字节对齐是我们初学C语言就会接触到的一个概念,但是到底什么是字节对齐?对齐准则又是什么?为什么要字节对齐呢?字节对齐对我们编程有什么启示?本文将简单理一理字节对齐的那些事。

    什么是字节对齐

    计算机中内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问某种基本数据类型,但是实际上,计算机并非逐字节大小读写内存,而是以2,4,或8的 倍数的字节块来读写内存,如此一来就会对基本数据类型的合法地址作出一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。

    对齐准则是什么

    总的来说,字节对齐有以下准则:

    • 结构体变量的首地址能够被其最大基本类型成员字节数大小所整除

    • 结构体每个成员相对结构体首地址的偏移都是成员大小的整数倍,如不满足,对前一个成员填充字节以满足。

    • 结构体的总大小为结构体对最大成员大小的整数倍,如不满足,最后填充字节以满足。

    我们通过一个小例子来说明是如何对齐的。
    考虑下面的程序:

    /*================================================================
    *   Copyright (C) 2018  Ltd. All rights reserved.
    *   
    * 文件名称:testByteAlign.c
    * 创 建 者:shouwang
    * 创建日期:2018年09月15日
    * 描 述:
    *
    ================================================================*/

    #include
    #include
    struct test
    {

        int a;
        char b;
        int c;
        short d;
    };
    int main(int argc,char *argv){
        /*在32位和64位的机器上,size_t的大小不同*/
        printf("the size of struct test is %zu
    "
    ,sizeof(struct test));
        return 0;
    }

    编译成32位程序并运行(默认四字节自然对齐),可以看到,结构体test 的大小为16字节,而不是11字节(a占4字节,b占1字节,c占4字节,d占2字节)

    #64位机器上编译32位程序可能需要安装一个库
    #sudo apt-get install gcc-multilib
    gcc -m32 -o testByteAlign testByteAlign.c #编译程序
    chmod +x testByteAlign  #赋执行权限
    ./testByteAlign  #运行
    the size of struct test is 16

    实际上,结构体test的成员在内存中可能是像下面这样分布的(数值为偏移量)
    未对齐时:

    0~345~910~11
    abcd

    对齐时:

    0~345~78~1112~1314~15
    ab填充内容cd填充内容

       从上面可以看出,c的偏移为5,不满足对齐要求(它的偏移量应该能够被sizeof(int)大小整除),因此在b后面填充了3个字节,使得c的偏移为8。在b后面填充后,d已经满足对齐要求了,为什么最后还要填充字节呢?或者说,为什么需要满足第三条准则呢?
    考虑下面的声明

    struct teArray[2];

       我们不难知道,teArray[0]的d如果不填充字节,那么teArray[1]的a偏移为14,不满足对齐要求,因此d后面也需要填充字节。

    为什么要字节对齐

            无论数据是否对齐,大多数计算机还是能够正确工作,而且从前面可以看到,结构体test本来只需要11字节的空间,最后却占用了16字节,很明显浪费了空间,那么为什么还要进行字节对齐呢?最重要的考虑是提高内存系统性能
           前面我们也说到,计算机每次读写一个字节块,例如,假设计算机总是从内存中取8个字节,如果一个double数据的地址对齐成8的倍数,那么一个内存操作就可以读或者写,但是如果这个double数据的地址没有对齐,数据就可能被放在两个8字节块中,那么我们可能需要执行两次内存访问,才能读写完成。显然在这样的情况下,是低效的。所以需要字节对齐来提高内存系统性能。
       在有些处理器中,如果需要未对齐的数据,可能不能够正确工作甚至crash,这里我们不多讨论。

    实际编程中的考虑

    实际上,字节对齐的细节都由编译器来完成,我们不需要特意进行字节的对齐,但并不意味着我们不需要关注字节对齐的问题。

    空间存储

    还是考虑前面的结构体test,其占用空间大小为16字节,但是如果我们换一种声明方式,调整变量的顺序,重新运行程序,最后发现结构体test占用大小为12字节

    struct test
    {

        int a;
        char b;
        short d;
        int c;
    };

    空间存储情况如下,b和c存储在了一个字节快中:

    0~3456~78~11
    ab填充内容cd

    也就是说,如果我们在设计结构的时候,合理调整成员的位置,可以大大节省存储空间。但是需要在空间和可读性之间进行权衡。

    跨平台通信

    由于不同平台对齐方式可能不同,如此一来,同样的结构在不同的平台其大小可能不同,在无意识的情况下,互相发送的数据可能出现错乱,甚至引发严重的问题。因此,为了不同处理器之间能够正确的处理消息,我们有两种可选的处理方法。

    • 1字节对齐

    • 自己对结构进行字节填充

    我们可以使用伪指令#pragma pack(n)(n为字节对齐数)来使得结构间一字节对齐。
    同样是前面的程序,如果在结构体test的前面加上伪指令,即如下:

    #pragma pack(1) /*1字节对齐*/
    struct test
    {

        int a;
        char b;
        int c;
        short d;
    };
    #pragma pack()/*还原默认对齐*/

    在这样的声明下,任何平台结构体test的大小都为11字节,这样做能够保证跨平台的结构大小一致,同时还节省了空间,但不幸的是,降低了效率。

    当然了对于单个结构体,如下的方法,使其1字节对齐

    struct test
    {

        int a;
        char b;
        int c;
        short d;
    }__attribute__ ((packed));

    注:

    • __attribute__((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。

    • __attribute__ ((packed)),取消结构在编译过程中的优化对齐,也可以认为是1字节对齐。

    除了前面的1字节对齐,还可以进行人为的填充,即test结构体声明如下:

    struct test
    {

        int a;
        char b;
        char reserve[3];
        int c;
        short d;
        char reserve1[2];
    };

    访问效率高,但并不节省空间,同时扩展性不是很好,例如,当字节对齐有变化时,需要填充的字节数可能就会发生变化。

    总结

    虽然我们不需要具体关心字节对齐的细节,但是如果不关注字节对齐的问题,可能会在编程中遇到难以理解或解决的问题。因此针对字节对齐,总结了以下处理建议:

    • 结构体成员合理安排位置,以节省空间

    • 跨平台数据结构可考虑1字节对齐,节省空间但影响访问效率

    • 跨平台数据结构人为进行字节填充,提高访问效率但不节省空间

    • 本地数据采用默认对齐,以提高访问效率

    • 32位与64位默认对齐数不一样   

    思考

    下面的结构体使用sizeof得到的大小是多少?

    struct test
    {

        char a;
        char b;
    };

    ●编号489,输入编号直达本文

    ●输入m获取文章

    C语言与C++编程

    9db6174edbcac296914b14256b29e17e.png

    分享C/C++技术文章

    展开全文
  • 2、32位系统中的偏移地址都为4个字节:因为寻址最小单位为bit,所以32/8bit=4Byte 为什么同样32位,一个4个G,另一个却4Byte呢? 直观说: 用在内存时:0x0000 0000到0xFFFF FFFF ----> 换成10进制...

    1、32位系统最多可以访问4个G的内存:因为寻址的最小单位为Byte,所以2^32/1024/1024/1024=4G

    2、32位系统中的偏移地址都为4个字节:因为寻址最小单位为bit,所以32/8bit=4Byte

    为什么同样是32位,一个是4个G,另一个却是4Byte呢?

    直观的说:

    用在内存时是:0x0000 0000到0xFFFF FFFF ---->  换成10进制是0到4,294,967,295‬ ------>就是0到2^32

    用在偏移是:0x0000 0000到0x0000 0004  ------> 就是0x0000 0000到0x0000 000(11111111 11111111 11111111 11111111)

    这样不知道大家能不能理解,第一个是转换成10进制的计算,第二个是bit的用法。

     

     

    展开全文
  • 我们转换其中一个图像,向左,右,上,或下滑动任何数量的单位,并把它放在另一个图像的上面。之后,该转换的重叠是指两个图像都具有 1 的位置的数目。 (请注意,转换不包括向任何方向旋转。) 最大可能的重叠...

    一、Problem

    给出两个图像 A 和 B ,A 和 B 为大小相同的二维正方形矩阵。(并且为二进制矩阵,只包含0和1)。

    我们转换其中一个图像,向左,右,上,或下滑动任何数量的单位,并把它放在另一个图像的上面。之后,该转换的重叠是指两个图像都具有 1 的位置的数目。

    (请注意,转换不包括向任何方向旋转。)

    最大可能的重叠是什么?

    输入:A = [[1,1,0],
              [0,1,0],
              [0,1,0]]
         B = [[0,0,0],
              [0,1,1],
              [0,0,1]]
    输出:3
    解释: 将 A 向右移动一个单位,然后向下移动一个单位。
    

    注意:

    1 <= A.length = A[0].length = B.length = B[0].length <= 30
    0 <= A[i][j], B[i][j] <= 1

    二、Solution

    方法一:枚举偏移量

    思路

    由于只需要对比移动后位置的值,所以并不需要真正去移动矩阵中的元素,比较简单的做法是:枚举偏移量 tx、ty,然后遍历矩阵,尝试将 A、B 都 “移动”,并记录移动后重叠 1 的个数

    class Solution {
    public:
        int largestOverlap(vector<vector<int>>& A, vector<vector<int>>& B) {
        	int n = A.size(), m = A[0].size(), ans = 0;
    
        	for (int tx = -n+1; tx < n; tx++)
        	for (int ty = -m+1; ty < m; ty++) {
        		int c1 = 0, c2 = 0;
        		for (int x = 0; x < n; x++)
        		for (int y = 0; y < m; y++) {
                    if (x+tx < 0 || y+ty < 0 || x+tx >= n || y+ty >= m) continue;
        			if (A[x+tx][y+ty] == B[x][y] && B[x][y] == 1) c1++;
        			if (B[x+tx][y+ty] == A[x][y] && A[x][y] == 1) c2++;
        		}
        		ans = max(ans, max(c1, c2));
        	}
        	return ans;
        }
    };
    

    我就很郁闷,下面两种写法的区别是什么

    //写法一
    for (int x = 0; x+tx < n && x+tx >= 0 && x >=0 && x < n; x++)
    for (int y = 0; y+ty < m && y+ty >= 0 && y >=0 && y < m; y++) {
    	if (A[x+tx][y+ty] == B[x][y] && B[x][y] == 1) c1++;
    	if (B[x+tx][y+ty] == A[x][y] && A[x][y] == 1) c2++;
    }
    //写法二
    for (int x = 0; x+tx < n && x >=0 && x < n; x++)
    for (int y = 0; y+ty < m && y >=0 && y < m; y++) {
        if (x + tx < 0 || x + tx >= n || y + ty < 0 || y + ty >= m) 
        	continue;
        if (A[x+tx][y+ty] == B[x][y] && B[x][y] == 1) c1++;
        if (B[x+tx][y+ty] == A[x][y] && A[x][y] == 1) c2++;
    }
    

    写法一对于这种例子求出来的答案是 0(错的),写法二正确…

    [[0,1],[0,0]]
    [[0,0],[1,0]]
    

    可能是因为 x 超界,而 x+tx 没有超界导致循环提早跳过了…

    复杂度分析

    • 时间复杂度:O(n4)O(n^4)
    • 空间复杂度:O(1)O(1)
    展开全文
  • 什么是指针

    2017-02-10 20:42:11
    1,指针的定义: 专门用来存放地址的变量 2,指针的应用场景 1,函数调用的时候(要去改变一个变量值得时候) 2,我们申请动态内存的时候需要指针 ...2,两个指针相减的作用两个指针的相差的单位,单位
    1,指针的定义:
    专门用来存放地址的变量




    2,指针的应用场景
    1,函数调用的时候(要去改变一个变量值得时候)
    2,我们申请动态内存的时候需要指针
    3,当我们想要去通过函数调用,改变一个指针的值时候用到二维指针






    3,指针运算:
    1,指针+-1的作用是指针偏移一个单位,单位由指针的类型所决定
    2,两个指针相减的作用是侧量两个指针的相差的单位,单位由指针的类型所决定,记得两个指针的类型必须严格一致




    4,const关键字:
    const修饰的变量具有只读的权限,没有写入的功能


    const int *p;
    int const *p;
    上面两个表达的意义是一样的,指针能改,指针所指向的地址的内容不能改


    int *const p;
    上面的意义是,指针不能改,指针所指向的地址的内容可以改









    展开全文
  • 内存中划分出按FIL0方式操作特殊区域,叫做堆栈 ...SS存放段基值,SP存放栈顶单元偏移量 SS:SP构成堆栈指针 物理地址SSx16+SP 常用于中断或子程序调用,存放返回地址,过程参数,保护数据等。
  • time模块和datetime模块time模块time模块中时间表现格式主要有3种:timestamp 时间戳:表示的是从1970年01月01日 00:00:00开始按秒计算的偏移量。即从1970年01月01日 00:00:00 距离当前时间,以秒为单位的总时间...
  • 计算机的内存管理单元以“字节”为最小单位进行线性编址的,字节80x86CPU对内存管理的基元。为了标识每个存储单元,就给每个存储单元规定一个编号,该编号就是内存...但是16位CPU存放存储单元偏移量的寄存器(IP,
  • 1、从底层实现上:foreach通过指针偏移实现(最初在-1位置,每循环一次,指针就便宜一个单位),而for循环通过当前索引相对零索引的偏移量(通过首地址和地址偏移量)计算实际访问地址实现; 2、从编码结构...
  • MatLab相机标定为什么有两个焦距

    千次阅读 2019-05-06 18:36:46
    其中Cx和Cy表示相机光轴在图像坐标系中的偏移量以像素为单位。但对于焦距fx和fy就不是很直观了。在我们使用相机针孔模型中,一个透镜焦距通常只有一个,那为什么一个相机会出现两个焦距呢?这就要从针孔相机...
  • 我们都知道计算机以字节(Byte)为单位划分,但是大部分处理器并不是按字节块来存取内存...1、第一个成员在与结构体变量偏移量为0地址 2、 其他成员变量要对齐到某个数字(对齐数)整数倍地址处。 3、对齐数
  • style.pixelLeft: 返回... style.posLeft返回定位元素左边界偏移量的数量值,不管相应的样式表元素指定什么单位.因为属性的非位置值返回的包含单位的字符串,例如,1.2em scrollLeft 设置或获取位于对象左边界和窗口中目
  • // 文件头最后到图像数据位开始的偏移量 }BMPHeader; #pragma pack() /* 位图数据信息结构*/ #pragma pack(1) typedef struct BMP_INFO { DWORD bInfoSize; // 结构大小 long bWidth; // 图像...
  • 内存中存储数据时,每个数据成员的偏移量必须此类型字节数整数倍。这就是所谓内存对齐。 为什么要内存对齐呢? (硬件原因)为了提升CPU执行速度 平台原因:并不所有硬件平台都能读取到任意地址上...
  • /*使用文件头字节偏移属性bfOffBits 直接把文件指针定位到像素值数据起始 */ fseek(pFile, file_h.bfOffBits, 0); fread(dataBuf, 1, w*h, pFile); unsigned char* data = dataBuf; u_int8_t* rgb = ...
  • CPU在读取内存地址时候,一定按照一定的偏移量去读取,不知道你发现了没有,我们没有看到一个变量大小 3 个字节,都 1 个字节,2个字节,4个字节,8个字节,16个字节,32个字节。 为什么会这样呢?因为CPU...
  • 批量归一化减少了隐藏单位的偏移量(协方差偏移)。为解释协方差变化,让我们深入了解猫检测。我们仅在黑猫图像上训练数据。因此,如果我们现在尝试将此网络应用于有色猫数据,那显而易见;我们做得不好。...
  • 关于相机内参中焦距fx和fy

    千次阅读 2019-07-20 19:28:42
    其中cx和cy很容易理解,它们表示相机光轴在图像坐标系中的偏移量,以像素为单位。但对于焦距fx和fy 就不是很直观了。为什么一个相机会出现两个焦距呢?在我们习惯使用相机针孔模型中,一个透镜焦距通常只有一个...
  • 那么问题来了,什么时候拉取偏移量会不合法? 概述 消息消费以消费组为单位,消费组可以订阅多个主题。每个消费组有两种模式,1.广播模式,一条消息被集群内所有消费者消费;2.集群模式,同一条消息只能被所有...
  • 一个程序发出虚拟地址由虚拟页面号和页内偏移值两部分组成,组成见下: 4.2 分页内存管理如何解决交换内存管理中两个问题? 1.空间浪费:通过将内存空间划分成大小一样页面,并且将其作为内存分配基本...
  • json时间转正常时间

    2015-12-22 12:27:05
    首先,在没有转之前,是这样,不懂菜鸟可能会疑惑,这瞄的是什么东西,其实根据在计算机里面时间,表示是从1970-1-1 00:00:00de 的偏移量单位是毫秒,所以看起来一个这么大数字,其实并不大,那么切入...
  • 分布式系统(二)

    2021-02-05 14:35:25
    时间和时钟Time and Clock 时钟有什么用处 1.知道发送请求到服务器需要...2.时钟漂移率 指由参考时钟度量每个单位时间内,时钟与参考的偏移量 同步系统对于最大时钟漂移率有个界限 两种同步方式 外部同步 如果需要
  • offset 与 style 区别

    2020-09-11 19:35:31
    offset 翻译过来就是偏移量, 我们使用 offset系列相关属性可以动态得到该元素位置(偏移)、大小等。 获得元素距离带有定位父元素位置 获得元素自身大小(宽度高度) 注意:返回数值都不带...
  • 什么是顺序表 顺序表指一段物理...基本布局顺序表存储的是同一类型数据,即每个数据元素占用存储单元大小都一样,所以对于该顺序表中元素读取就可以依靠各个数据元素物理地址偏移量; 元素外置顺...
  • //计算并输出位图数据的偏移量,图像大小,宽度和高度,每个像素点所占字节 size = fileHeader.bSize; offset = fileHeader.bOffset; bmpImageSize = infoHeader.bmpImageSize; width = infoHeader.bWidth;...
  • 什么是分段什么是段表如何...逻辑地址:段号(段名)和段内地址(段内偏移量)所组成段号位数决定了每个进程最多可以分几个段段内地址位数决定了每个段最大长度多少分段用户进程地址空间二维,程序员需...
  • Batch normalization--NN

    2020-05-07 03:45:55
    首先,我们将说明为什么需要它,它如何工作,然后如何将其包含在经过预训练网络中。 为什么要使用批处理规范化? 我们通过调整和缩放激活函数来标准化输入层。...批量归一化减少了隐藏单位的偏移量(...
  • 数据库索引

    2020-10-08 21:26:49
    索引帮助mysql高效查找数据结构,如某索引记录了当前索引数据在哪一个文件中,文件中的偏移量 索引存储在文件系统中,索引文件存储形式与存储引擎有关 索引数据结构 b+树(叶子节点不存数据实例,可以存很多...
  • 最近公司要上CDN网络,做一些视频缓存,为了用... 首先简单了解一下视频为什么能拖动,使用yamdi等视频加帧软件将视频加帧生成metadata信息,里面记录着每一帧对应文件以字节为单位的偏移量(offset),播放器...
  • java常用工具类使用

    热门讨论 2012-03-19 20:11:37
    Q 老师,时间毫秒值从1970年1月1日0:00.000开始计算,上面示例中10年后应该1980年1月1日0:00.000,为什么输出结果:1980年1月1日 8:00呢? A java.util.Date类型表示的是GMT时间,本身输出国际化输出,...
  • 答:分段部件形成32位线性地址中高10位作为寻址页目录表的偏移量,与控制寄存器CR3中页目录表基地址共同形成一个32位地址指向页表中一个页项,即为一个页面描述符。该页面项中高20位作为页面基地址,线性地址...

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

偏移量的单位是什么