返回首页  设为首页  加入收藏  今天是:
网站首页电脑主板电脑cpu电脑内存电脑硬盘电脑显卡电脑电源显示器电脑配件电脑维修
相关文章
 C语言、C++内存对齐问题详解
 ddr4和ddr3区别内存对电脑性…
 内存对齐 - 道客巴巴
 新闻简讯存储_DIY电脑硬件频…
 电脑内存条在哪网卡的英文怎…
 显卡资讯-显卡相关资讯-天极…
 什么显卡品牌比较受欢迎 202…
 最新显卡天梯图:2021年4月A…
 显卡_DIY电脑硬件频道_天极网
 2020年双11台式机显卡选购指…
 组装电脑配置清单
 台式机电脑主流配置推荐
 组装机配置清单 2016DIY电脑…
 2016最新主流电脑配置推荐清…
 2020热门品牌游戏主机推荐 不…
 想要避开SMR的坑硬盘就该这样…
 希捷 Osprey 机械硬盘新品经…
 4月硬盘涨价可信吗?炒币不是…
 M2 SSD秒变移动硬盘!酷冷至…
 超大满足!4TB固态硬盘跌破1…
 华硕显卡系列排名
 来看看你的显卡属于几线品牌…
 华硕预告 RTX 4090 显卡:猛…
 全系满功耗显卡!华硕天选4系…
 30系显卡供货稳定3张华硕显卡…
 未来电商高峰论坛在杭召开
 评分高清华同方宽屏16:9
 买海信电视强烈建议这三款观…
 全系灵动岛!iPhone 15系列显…
 视爵光旭启明系列超薄超轻小…
 创维75英寸超薄护眼巨幕影院…
 CPU性能排行天梯图2019 CPU天…
 紫光发布Unis L3891笔记本电…
 有了笔记本充电柜学校再也不…
 2023年Q1季度搭载酷睿i9-139…
 【巽雷周年庆】满额抽大奖送…
 主板全面注册制开门纳客:“…
 2023年预算8千封顶大概能装台…
 冲刺深交所主板IPO:阿宽食品…
 全面注册制首批IPO迎“大考”…
 推荐三款AMD锐龙5 5600G5600…
 冲着外观去的没想到这么能超…
 佰维存储:公司目前暂未涉及…
 “APP刺客”倒逼厂商升级大内…
 前三大内存供应商占前沿制程…
 淘汰8GB 一加Ace 2V手机普及…
 AMD承认Radeon显卡驱动错误 …
 慧聪产经网_慧聪产业经济
 显示器小科普_游戏_支持_都能
 硬核配置强悍性能三星玄龙骑…
专题栏目
网络
您现在的位置: 电脑评测网 >> 电脑内存 >> 正文
高级搜索
C语言、C++内存对齐问题详解
作者:佚名 文章来源:本站原创 点击数: 更新时间:2023/3/8 5:39:30 | 【字体:

  夜深人静给个网站好了,一段简单的程序,上面的这段程序输出是什么?如果你很懂,也就会知道我接下来要讲什么了,可以略过了;如果,你不知道,或者还很模糊,请继续阅读。

  很奇怪么?定义的三个结构体,只是换了一下结构体中定义的成员的先后顺序,怎么最终得到的结构体所占用的内存大小却不一样呢?很诡异么?好了,这就是我这里要总结的内存对齐概念了。

  内存对齐的问题主要存在于理解struct和union等复合结构在内存中的分布。许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。这个值k在不同的CPU平台下,不同的编译器下表现也有所不同,现在我们涉及的主流的编译器是Microsoft的编译器和GCC。

  对于我们这种做上层应用的程序员来说,真的是很少考虑内存对齐这个问题的,内存对齐对于上层程序员来说,是“透明的”。内存对齐,可以说是编译器做的工作,编译器为程序中的每个数据块安排在适当的内存位置上。很多时候,我们要写出效率更高的代码,此时我们就需要去了解这种内存对齐的概念,以及编译器在后面到底偷偷摸摸干了点什么。特别是对于C和C++程序员来说,理解和掌握内存对齐更是重要的。

  为什么要有内存对齐呢?该占用多大的内存,那就开辟对应大小的内存就好了,好比上面的结构体,两个char类型和一个int类型,大小应该是6bytes才对啊,怎么又是8bytes,又是12bytes的啊?对于内存对齐,主要是为了提高程序的性能,数据结构,特别是栈,应该尽可能地在自然边界上对齐。原因在于,为了访问未对其的内存,处理器需要做两次内存访问;然而,对齐的内存访问仅仅需要一次内存访问。

  在计算机中,字、双字和四字在自然边界上不需要在内存中对齐(对字、双字和四字来说,自然边界分别是偶数地址,可以被4整除的地址和可以被8整除的地址)。如果一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,就被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数,但却没有跨越字边界,就被认为是对齐的,能够在一个总线周期中被访问。综上所述,内存对齐可以用一句话来概括——数据项只能存储在地址是数据项大小的整数倍的内存位置上。

  结构体Test的成员变量b占用字节数为4bytes,所以只能存储在4的整数倍的位置上,由于a只占用1一个字节,而a的地址00C7FA44和b的地址00C7FA48之间相差4bytes,这就说明,a其实也占用了4个字节,这样才能保证b的起始地址是4的整数倍。这就是内存对齐。如果没有内存对齐,我们再拿上面的代码作为例子,则可能输出结果如下:

  可以看到,a占用了一个字节,紧接着a之后就是b;之前也说了,内存对齐是操作系统为了快速访问内存而采用的一种策略,简单来说,就是为了防止变量的二次访问。操作系统在访问内存时,每次读取一定的长度(这个长度就是操作系统的默认对齐系数,或者是默认对齐系数的整数倍)。没有了内存对齐,当我们读取变量c时,第一次读取0xffbff5e8~0xffbff5ef的内存,第二次读取0xffbff5f0~0xffbff5f8的内存,由于变量c所占用的内存跨越了两片地址区域,为了正确得到变量c的值,就需要读取两次,将两次内存合并进行整合,这样就降低了内存的访问效率。

  我在这里说了这么多,也挺绕口,这就是内存对齐的规则。在C++中,每个特定平台上的编译器都有自己的内存对齐规则,下面我们就内存对齐的规则进行总结。

  每个特定平台上的编译器都有自己的默认“对齐系数”。我们可以通过预编译命令#pragma pack(k),k=1,2,4,8,16来改变这个系数,其中k就是需要指定的“对齐系数”;也可以使用#pragma pack()取消自定义字节对齐方式。具体的对齐规则如下:

  规则1:struct或者union的数据成员对齐规则:第一个数据成员放在offset为0的地方,对齐按照#pragma pack指定的数值和自身占用字节数中,二者比较小的那个进行对齐;比如;

  #pragma pack(4) // 指定对齐系数为4,当占用字节数大于等于4时,就按照4进行对齐

  x1占用字节数为1,1 4,按照对齐系数1进行对齐,所以x1放置在offset为0的位置;

  x2占用字节数为2,2 4,按照对齐系数2进行对齐,所以x2放置在offset为2,3的位置;

  x3占用字节数为4,4 = 4,按照对齐系数4进行对齐,所以x3放置在offset为4,5,6,7的位置;

  x4占用字节数为1,1 4,按照对齐系数1进行对齐,所以x4放置在offset为8的位置;

  现在已经占了9bytes的内存空间了,但是实际在visual studio 2012中实测为12bytes,为什么呢?看下一条规则。

  规则2:struct或者union的整体对齐规则:在数据成员完成各自对齐以后,struct或者union本身也要进行对齐,对齐将按照#pragma pack指定的数值和struct或者union中最大数据成员长度中比较小的那个进行;

  继续使用规则1种的例子进行解释,按照规则1的理解,struct Test已经占用了9bytes,实际为什么是12bytes呢?根据规则2,在所有成员对齐完成以后,struct或者union自身也要进行对齐;我们设定的对齐系数为4,而struct Test中占用字节数最大的是float类型的x3,由于x3占用字节数小于或等于设定的对齐系数4,所以struct或者union整体需要按照4bytes进行对齐,也就是说,struct或者union占用的字节数必须能够被4整除,好了。struct Test已经占用了9bytes了,10bytes不能被4整除,11bytes也不能,12bytes正好;所以,struct Test最终占用的字节数为12bytes。

  总结了那么多的规则,不来点实际的code,总觉的少点什么,好吧。以下就按照上述总结的内存对齐规则,来进行一些实际的代码分析(注:测试环境Windows 8.1 + Visual Studio 2012 update 3)。

  经过上面的实例分析,我对内存对齐有了全面的认识和了解。现在再回过来看看文章开头的那段代码,问题就迎刃而解了,同时经过这段代码,让我们认识到定义struct或者union时,也是有讲解的。在以后的编码生涯时,是不是又要多考虑一些呢?纠结~

电脑内存录入:admin    责任编辑:admin 
  • 上一个电脑内存:

  • 下一个电脑内存: 没有了
  •  
     栏目文章
    普通电脑内存 C语言、C++内存对齐问题详解 (03-08)
    普通电脑内存 ddr4和ddr3区别内存对电脑性能提升有大作用 (03-08)
    普通电脑内存 内存对齐 - 道客巴巴 (03-08)
    普通电脑内存 新闻简讯存储_DIY电脑硬件频道-YESKY天极网 (03-08)
    普通电脑内存 电脑内存条在哪网卡的英文怎么写 (03-08)
    普通电脑内存 冲着外观去的没想到这么能超十铨科技DELTA炫光… (03-07)
    普通电脑内存 佰维存储:公司目前暂未涉及HBM内存产品 (03-07)
    普通电脑内存 “APP刺客”倒逼厂商升级大内存、大存储!8+1… (03-07)
    普通电脑内存 前三大内存供应商占前沿制程产能的四分之三 (03-07)
    普通电脑内存 淘汰8GB 一加Ace 2V手机普及16GB:没大内存就… (03-07)
    普通电脑内存 手机行业普及大内存?“APP刺客”立大功 (03-07)
    普通电脑内存 红米K50是5G双卡双待吗 pro可以插内存卡吗? (03-07)
    普通电脑内存 13400支持多少频率内存 (03-06)
    普通电脑内存 AMD和Intel至今没有放开桌面四通道和RECC内存… (03-06)
    普通电脑内存 DDR5内存也要上双风扇 (03-06)
    普通电脑内存 256GB被吃掉220GBiOS13用户注意了:苹果怎么释… (03-06)
    普通电脑内存 市交通委谈“2022年北京冬奥会延庆赛区外围道… (03-06)
    普通电脑内存 中国最强天团「外交部」的英文翻译有多牛?连… (03-06)
    普通电脑内存 写公文时为什么要用仿宋GB2312字体? (03-06)
    普通电脑内存 手机存储里的提示视频占用三十多G为什么点进去… (03-05)