VC内存对齐准则(Memory alignment)

***************************************************

更多精彩,欢迎进入:http://shop115376623.taobao.com

***************************************************


本文所有内容在建立在一个前提下:使用VC编译器。着重点在于:VC的内存对齐准则;同样的数据, 不同的排列有不同的大小,另外在有虚函数或虚拟继承情况下又有如何影响?

内存对齐?!What?Why?

对于一台32位的机器来说如何才能发挥它的最佳存取效率呢?当然是每次都读4字节(32bit)(一个字节8位,一次读取4个字节,刚好满负荷读取), 这样才可以让它的bus处于最高效率。实际上它也是这么做的,即使你只需要一个字节,它也是 读一个机器字长(这儿是32bit)。更重要的是,有的机器在存取或存储数据的时候它要求数据 必须是对齐的,何谓对齐?它要求数据的地址从4的倍数开始,如若不然,它就报错。还有的机 器它虽然不报错,但对于一个类似int变量,假如它横跨一个边界的两端,那么它将要进行两次 读取才能获得这个int值。比方它存储在地址为2~5的四个字节中,那么要读取这个int,将要 进行两次读取,第一次读取0~3四个字节,第二次读取4~7四个字节。但是如果我们把这个整 形的起始地址调整到0,4,8…呢?一次存取就够了!这种调整就是内存对齐了。我们也可以依次 类推到16位或64位的机器上。

边界该如何调整

对于32位的机器来说,它当然最渴望它的数据的大小都是4 Byte或者4的倍数Byte,这样它就能 最有效率的存取数据,当然如果数据小于4Byte,那也是没问题的。那么编译器要做的便是尽量满 足这个要求。

这两天我断续对VC做了一些实验,并总结如下三条准则,你要明白的是这并非来自微软的官方文 档,但我自以为这些准则或许不全但应该都是正确的:

  • 变量存放的起始位置2应为变量的大小与规定对齐量1中较小者的倍数。例如,假 设规定对齐量为4,那么char(1byte)变量应该存储在偏移量为1的倍数的地方,而整形变 量(4byte)则是从偏移量为4的倍数的地方,而double(8 byte)也同样应存储在偏移量为 4的倍数的地方,为什么不是8?因为规定对齐量默认值为4,而4 < 8。在VC中默认对齐量 为8,而非4
  • 结构体整体的大小也应该对齐,对齐依照规定对齐量与最大数据成员两者中较小的进行。
  • Vptr影响对齐而VbcPoint(Virtual base class pointer)不影响。

一个实例

对于类T:

class T{char c;int i;double  d;};

将其sizeof输出后的大小为16,其内存布局如图T.变量c从偏移量为0开始存储,而整形i第一个 符号条件的偏移量为4,double型d的第一个符号条件的为8。整个对象的大小为16,不需要再进 行额外的对齐。

图T(类T 的内存布局) :

同样的数据,不同的大小

再看类L,它与T存储同样类型的数据,仅仅是顺序不同罢了,那么它sizeof输出的大小是多少呢?

类L:

class L{char c;double  d;int i;};

它sizeof后的结果或许会令你大吃一惊,或许不会(如果你有认真读前面的两条准则)。L sizeof后的结果是24!同样是一个int,一个char,一个double却整整多出了8个字节。这期间 发生了什么?我们依据前面两条规则来看看。C存储于0的位置,1~7都不能整除8,所以d存储 在8~15,16给i正好合适,i存储在16~19。总共花费了20个字节,抱歉不是8的倍数,还得补 齐4个。现在你可以看看图L的关于类L的内存布局,再比较一下类L和类T的内存布局。

图L(类L的布局)

我得出了这样一条并不权威的结论,因为我还没听有人这样说过:在声明数据成员的时候,将 最大字节数的变量放在最前面3,切忌不要将大小差距很大的类型交替声明。

Vptr影响对齐而VbcPoint(Virtual base class pointer)不影响

前面的实例只涉及前两条准则,现在我们来看看第三条的两个实例:

class X{char a;};
class Y: virtual public X{};

Y的大小为:a占一个字节,VbcPoint(我称他为虚基类指针)占四个字节。我们不论a与VbcPoint 的位置如何摆放,如果将VbcPoint等同于一个成员数据来看的话,sizeof(Y)都应该为8.实际上 它是5!就我目前的水平,我只能先将其解释为VbcPoint不参与对齐。

对于vptr这个问题则不存在:

class X{char a;virtual int vfc(){};}

sizeof(X)的大小确实为8.

关于#pragma pack(n)

用#pragma pack(n)改变规定对齐量试试眨眼


  1. 规定对齐量:实际上并没有这么一个名词,是我为了方便而造出来的。在VC中这个“规定对齐量”会有一个默认值,这个默认值一般为8,我原来一直以为这个值以为是4,至于它为什么为8,我现在还不知道。。我们也可以通过#pargma pack(n)来规定这个值,目前n可以为1,2,4,8,16。 ↩

  2. 这个起始位置指的是相对于结构体(类)来说的。 ↩

  3. 此处有一点问题,这个问题由独酌逸醉提出,他认为将最小的数据放在最前面可能会更好,我们有进行过讨论,但可惜的是由于在2011/11/24日数据库丢失,我只能用备份还原,所以丢失了一些数据,无疑,本文的评论也在其中。不过我对这个问题映像深刻,因为我在写这篇博客的时候便困惑于到底成员是应该放在之前还是之后,因为这两种情况我都找不到强有力的理由来支撑它们。后来使我确信从大到小排列好于从小到大排列的理由在于,从大到小排列一般无需成员之间的对齐,唯一的对齐工作是最后进行的整个结构体对齐的工作。毫无疑问的是,这应该是最节省内存的方式。再之后,独酌提出从小到大可能好些,虽然没有给出有说服力的理由,但却使我无比困惑,我当时虽然认为从大到小的排列更有优势,但却实在想不出一个实例能使得它优于从小到大排列的。不过最终我击垮了自己的理由,在继承状况下从大到小排列很容易被打破,比方,基类的成员为一个char,继承类的成员为double,int,char虽然基类和继承类都是按从大到小的顺序排列的,但是继承类的内存布局最终会使char,double,int,char,此时既不能避免成员对齐,又导致后面的结构体对齐。暂时获得的最终结果是从小到大排列是更好的一种排列方式。(2011/12/31增补) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 主主互备实现

今天星期天&#xff0c;么事就写个MYSQL的主主架构的博客&#xff0c;原理如下图&#xff0c;不是我画的网上找的。主机作用操作系统mysql版本对应IPvip数据库mysqlA(主)centos6.4mysql 5.5.48192.168.48.129192.168.48.126mysqlB(备)centos6.4mysql 5.5.48192.168.48.132一&am…

动手实践 Linux VLAN - 每天5分钟玩转 OpenStack(13)

本节我们来看如何在实验环境中实施和配置如下 VLAN 网络 配置 VLAN 编辑 /etc/network/interfaces&#xff0c;配置 eth0.10、brvlan10、eth0.20 和 brvlan20。 下面用 vmdiff 展示了对 /etc/network/interfaces 的修改 重启宿主机&#xff0c;ifconfig 各个网络接口 用 brct…

Socket的3次握手链接与4次断开握手

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 连接握手&#xff1a; 1.客户端发送建立连接请求 &#xff08;发送请求&#xff09;2.…

Linux桌面需要强制访问控制,RHCSA 系列(十三): 在 RHEL 7 中使用 SELinux 进行强制访问控制...

RHCSA 认证&#xff1a;SELinux 精要和控制文件系统的访问尽管作为第一级别的权限和访问控制机制是必要的&#xff0c;但它们同样有一些局限&#xff0c;而这些局限则可以由安全增强 Linux(Security Enhanced Linux&#xff0c;简称为 SELinux)来处理。这些局限的一种情形是&am…

使用canvas实现擦玻璃效果

体验效果:http://hovertree.com/texiao/html5/25/效果图&#xff1a;代码如下&#xff1a; <!DOCTYPE html> <html> <head lang"zh"> <meta name"viewport" content"initial-scale1.0, maximum-scale1.0, user-scalableno, widt…

[转]opencv学习资料

转自&#xff1a;http://blog.csdn.net/poem_qianmo/article/details/20537737 1&#xff1a;Mat imread(const string& filename, intflags1 ); eg: Mat image0imread("dota.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);//载入最真实的图像 ge1i…

jQuery动态设置样式List item

前段时间&#xff0c;Insus.NET有修改一个功能《激活当前视图菜单高亮呈现》http://www.cnblogs.com/insus/p/5287093.html 今天Insus.NET想改用另外一个方法来实现&#xff0c;使用jQuery。在ASP.NET MVC 环境实现&#xff1a; 代码&#xff1a; <ul><li><a hr…

linux telnet 权限,允许telnet 通过root用户进行访问

允许telnet 通过root用户进行访问RHEL6:[rootclovem ~]# yum install telnet-server -y //安装telnet服务端[rootclovem ~]# cat /etc/xinetd.d/telnet //开启telnet的托管服务# default: on# description: The telnet server serves telnet sessions; it uses \#unencrypt…

TOUGHRADIUS 项目介绍

2019独角兽企业重金招聘Python工程师标准>>> TOUGHRADIUS 项目介绍 ToughRADIUS是一个开源的Radius服务软件&#xff0c;采用于 Apache License 2.0 许可协议发布&#xff0c;从创立之日起&#xff0c;他的宗旨就是服务于中小微ISP&#xff0c;让运营变得更简单。 T…

转:Jmeter 用户思考时间(User think time),定时器,和代理服务器(proxy server)...

在负载测试中需要考虑的的一个重要要素是思考时间&#xff08;think time&#xff09;&#xff0c; 也就是在两次成功的访问请求之间的暂停时间。 有多种情形挥发导致延迟的发生&#xff1a; 用户需要时间阅读文字内容&#xff0c;或者填表&#xff0c;或者查找正确的链接等。未…

linux sql语句传参数,Linux/Unixshell参数传递到SQL脚本

在数据库运维的过程中&#xff0c;Shell 脚本在很大程度上为运维提供了极大的便利性。而shell 脚本参数作为变量传递给SQL以及SQL脚本也是DB在数据库运维的过程中&#xff0c;Shell 脚本在很大程度上为运维提供了极大的便利性。而shell 脚本参数作为变量传递给SQL以及SQL脚本也…

Myeclipse5.5获取注册码

2019独角兽企业重金招聘Python工程师标准>>> import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class MyEclipseGen {private static final String LL "Decompiling this copyrighted software is a vi…

对互联网中常见地图的坐标系探讨

文章版权由作者李晓晖和博客园共有&#xff0c;若转载请于明显处标明出处&#xff1a;http://www.cnblogs.com/naaoveGIS/。 1.背景 目前项目中使用百度地图、高德地图、谷歌中国地图、天地图的需求越来越多&#xff0c;这里我跟大家一起对各地图使用的坐标系做一个简单的探讨。…

讯飞输入法有没有Linux,Debian testing 安装讯飞输入法 - Linux系统与应用 - LinuxApp - 水木社区...

突然发现Deepin发行版带有讯飞输入法&#xff0c;于是折腾了一会&#xff0c;安装好了这个输入法&#xff0c;现把安装过程分享如下&#xff1a;软件包的依赖&#xff1a;Package: iflyimeVersion: 0.9.962Section: develPriority: optionalArchitecture: amd64Depends: libboo…

HTTP必知必会

2019独角兽企业重金招聘Python工程师标准>>> HTTP消息HTTP请求消息HTTP响应消息消息首行请求行响应行消息头部请求头请求头消息正文请求正文响应正文Web服务器把接收到的HTTP请求消息封装成request对象&#xff0c;作为service的参数传入service函数&#xff0c;ser…

更新10_linux,时隔十年,QQ更新了Linux版本

昨天1024程序员节&#xff0c;QQ悄悄地更新了QQ for Linux&#xff0c;也许是给各位一个惊喜吧。官网及其的简陋。和一个Word文档似的。十年一更&#xff0c;有网友称&#xff0c;瞬间回到QQ2006&#xff0c;确实界面功能有些落后&#xff0c;相信QQ可以跟上潮流的&#xff0c;…

C语言里if语句变量作为判断条件,C语言教学(九-上)if else判断语句

原标题&#xff1a;C语言教学(九-上)if else判断语句今天讲if else判断语句&#xff0c;简单理解就是进行条件判断&#xff0c;如果条件达到则执行if 里或else里的语句。先来看if。if的写法和for差不多,就是不用括号里的两个分号&#xff0c;if (条件) { }&#xff0c;if加括号…

二维数组联通子数组和最大

题目要求&#xff1a; 返回一个二维整数数组中最大联通子数组的和。输入一个二维整形数组&#xff0c;数组里有正数也有负数。文件输出。思路:和之前的动态规划相识&#xff0c;把二维数组转换为一维数组&#xff0c;先求每一个列的子数组和最大&#xff0c;最后在用正数就加&a…

Win10 IIS本地部署网站运行时图片和样式不正常?

后期会在博客首发更新&#xff1a;http://dnt.dkill.net 异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 启用关闭win功能&#xff0c;开启一下静态内容 收工~

设置IIS会话过期时间

打开默认网站----双击ASP--展开会话属性---更改超时时间-转载于:https://www.cnblogs.com/genesis/p/4816128.html