教你5分钟轻松搞定内存字节对齐_C 语言

写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧.

/******************************分割线

如果体系结构是不对齐的,A中的成员将会一个挨一个存储,从而sizeof(a)为11。显然对齐更浪费了空间。那么为什么要使用对齐呢?

体系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据的处理最频繁也是最重要的。它的设计也是从优先提高对w位数据操作的效率来考虑的。比如说读写时.............此处省略50万字

*******************************************************/

上面是你随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则:(在没有#pragma pack宏的情况下,务必看完最后一行)

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

等你看完此3条原则,2分钟已经过去,抓紧时间,实战3分钟:

复制代码 代码如下:

typedef struct bb
{
 int id;             //[0]....[3]
 double weight;      //[8].....[15]      原则1
 float height;      //[16]..[19],总长要为8的整数倍,补齐[20]...[23]     原则3
}BB;

typedef struct aa
{
 char name[2];     //[0],[1]
 int  id;         //[4]...[7]          原则1

 double score;     //[8]....[15]    
 short grade;    //[16],[17]        
 BB b;             //[24]......[47]          原则2
}AA;

int main()
{
  AA a;
  cout<<sizeof(a)<<" "<<sizeof(BB)<<endl;
  return 0;
}

结果是

48 24
ok,上面的全看明白了,内存对齐基本过关.

再讲讲#pragma pack().

在代码前加一句#pragma pack(1),你会很高兴的发现,上面的代码输出为

32 16
bb是4+8+4=16,aa是2+4+8+2+16=32;

这不是理想中的没有内存对齐的世界吗.没错,#pragma pack(1),告诉编译器,所有的对齐都按照1的整数倍对齐,换句话说就是没有对齐规则.

明白了不?

那#pragma pack(2)的结果又是多少呢?对不起,5分钟到了,自己去测试吧.

ps:Vc,Vs等编译器默认是#pragma pack(8),所以测试我们的规则会正常;注意gcc默认是#pragma pack(4),并且gcc只支持1,2,4对齐。套用三原则里计算的对齐值是不能大于#pragma pack指定的n值。

时间: 2024-11-05 12:26:57

教你5分钟轻松搞定内存字节对齐_C 语言的相关文章

用Photoshop滤镜三分钟轻松搞定拼图

滤镜 女儿最喜欢玩拼图游戏,每次买拼图玩具的理由就是它们的画面不一样.家里的拼图玩具堆成山,可是她的兴致依然不减. 一天,我上网时无意中发现了Photoshop的一款制作拼图的滤镜--AV Bros.公司的Puzzle Pro滤镜.下载回来一试,果然效果不错!女儿喜欢的拼图玩具仅用三分钟就轻松搞定了.好东西不敢独享,下面我就给大家详细介绍一下. 首先,到http://download.sina.com.cn/cgi-bin/detail.cgi?s_id=8779去下载并安装这款滤镜,关于如何安

只需一分钟轻松搞定Win7桌面假死问题

很多使用Win7的用户都会遇到一个问题就是关于Win7桌面假死的情况,如何来避免这种不必要的麻烦呢,重装系统吗?这当然是个不太明智的选择,如果不重装系统,但是电脑会时不时的卡上一段时间,这也会让广大用户恼火一阵了.那么是因为什么原因Win7会出现假死的情况呢?首先要确定你购买 Win7安装的是正版系统,这不仅确保Win7桌面不会经常出现蓝屏的状况,也维护了你购买Win7的权益.其次,我来介绍给大家几种遇到Win7假死的情况下如何解决的方法. Win7桌面 一.开机的时候电脑出现假死 在开机进入桌

手机储存空间不足?ROM助手轻松搞定

在使用安卓智能手机时,经常会出现"存储空间不足"的提示,相信更多的人一定尝试过删除无用照片或视频,卸载APP等来缓解此类情况,但不久又会收到同样的提示,实在让人着急,甚至有些手机里的顽固软件根本无法删除,其实面对储存空间不足的状况,我们只需要借助ROM助手(及相关编辑制作工具)一键删除即可轻松搞定!我们应该知道,手机存储空间并不是单指内存卡,而是指ROM空间的大小,一般即便ROM空间很大,但真正可以用来 预装软件和数据的空间依然非常少,无论是国产还是国外产的安卓手机,大多是16G,32

一步一步轻松搞定您的个人数码免冠照

应用目标:制作证件照片 使用软件:Photoshop 7.0(其他版本操作类似) 实现难度:即学即会 相信许多朋友都有这样的经历:填写应聘表.考个驾照或是办个工作证经常会用到免冠照,可每次都想不起来上回留下的底(照)片放在哪里,回到家里翻天覆地地一阵好找,结果常常是无功而返,最后只好一边抱怨自己记性不好一边梳妆打扮走进照相馆,一番讨价还价之后,然后极不情愿地把银子数给照相馆老板,到了下回这样的情形依然会重现.要是我们做好一个无需底片的数码免冠照存在个人电脑或软盘里,随用随扩,岂不是要省掉许多麻烦

轻松搞定jQuery.noConflict()_jquery

jQuery是目前使用最广泛的前端框架之一,有大量的第三方库和插件基于它开发.为了避免全局命名空间污染,jQuery提供了jQuery.noConflict()方法解决变量冲突.这个方法,毫无疑问,非常有效.遗憾的是,jQuery的官方文档对该方法的描述不够清晰,许多开发者并不清楚当他们调用jQuery.noConflict()时,究竟发生了什么,从而导致在使用时出现了许多问题.尽管如此,jQuery.noConflict()背后实现原理依然值得Web开发者学习掌握,成为解决类似全局命名空间污染

用美图秀秀轻松搞定绝美雪夜樱花图

美图秀秀(美图大师)是新一代的图片处理软件,可以1分钟搞定个性的非主流图片.非主流闪图.http://www.aliyun.com/zixun/aggregation/29890.html">QQ头像.QQ空间图片--比Photoshop简单100倍,超好用! 美图秀秀也是史上最"傻瓜",人人都会用! "美图秀秀"界面直观,操作简单,比同类软件更好用!每个人都能轻松上手,从此做图不求人! 超喜欢收集一些美美的签名图,但是好像特别漂亮的签名图做起来很麻

Illustrator轻松搞定SVG ICON的模糊问题分享

给各位Illustrator软件的使用者们来详细的解析分享一下轻松搞定SVG ICON的模糊问题. 分享一览:   @京东设计中心 :很多设计师跟开发都会遇到SVG 图标模糊的问题,今天我们简单教你四招,轻松搞定这个问题,有需要的同学赶紧来收 >>> 简单介绍 随着高清视网膜屏的出现,网页设计也需要考虑各种高清屏幕的显示效果,前端在写代码的时候也需要根据屏幕的不同,输出不同分辨率的icon图片,真的好多工作量啊~ 为了解决屏幕分辨率对图标影响的问题,SVG格式的icon出现了,简单的说它

几行代码轻松搞定网页的简繁转换

简繁转换|网页 对网页进行简繁字体转换的方法一般有两种:一是使用<简繁通>这样的专业软件,另外一种是制作两套版本的网页.显然,这两种方法都较为麻烦,而且专业软件一般不能用于免费的空间.笔者在这里给大家提供一个非常简单的方法,只须在页面上添加几行代码就可以轻松搞定网页的简繁转换了.首先在http://www.knowsky.com/download/transform.js处下载用于简繁转换的js文件transform.js,复制到网站目录下,然后使用网页制作工具打开需要进行简繁转换的网页,

轻松搞定数据访问层[续]

访问|数据 数据库表 Tbl_Teacher 数据字段名称 类型 说明 teaID Int 自动编号 teaCode Char(20) 教师员工号 teaName Nchar(10) ? teaGender Bit ? teaNation Nchar(6) ? teaAge TinyInt ? Tbl_Student 数据字段名称 类型 说明 stuID Int 自动编号 stuCode Char(20) 学生证号 stuTeacherCode Char(20) 班主任的员工号 stuName