5分钟搞懂字节对齐

转载 2016年08月31日 10:21:53

写出一个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值。

五分钟搞懂后缀数组!后缀数组解析以及应用(附详解代码)

这是一篇本人自己对后缀数组的一些理解,有详细的说明以及附有详解的代码。...
  • YxuanwKeith
  • YxuanwKeith
  • 2016年02月05日 13:13
  • 16200

10分钟搞懂git和github(该教程只适合快速入门)

目录 目录 正文 一 git的安装配置只有初次使用需要配置 用户名和邮件 ssh-keygen -t rsa 添加公钥 二最基础本地git操作若这步看不懂请先看四 三 关联远程github的操作 四...
  • u013497977
  • u013497977
  • 2017年01月09日 18:53
  • 1320

深度学习导论 - 读李宏毅《1天搞懂深度学习》

先引用他人关于李宏毅教授关于深度学习导论的PPT,应该非常容易入门。 ”《1天搞懂深度学习》,300多页的ppt,台湾李宏毅教授写的,非常棒。不夸张地说,是我看过最系统,也最通俗易懂的,关于...
  • u010164190
  • u010164190
  • 2017年05月22日 23:44
  • 9220

带你5分钟搞懂 block 回调

Objective-C 中的 block 是一个类似于其他语言如 swift 中的闭包的东西。掌握好 block 的使用方法,可在项目开展中得心应手,比较常用的是 block 的回调机制。下面就由具体...
  • huangfei711
  • huangfei711
  • 2017年06月29日 21:54
  • 868

一张表搞懂各种 Docker 监控方案 - 每天5分钟玩转 Docker 容器技术(86)

本文从五个维度对比 ps/top/stats、Sysdig、Weave Scope、cAdvisor 和 Prometheus​。
  • CloudMan6
  • CloudMan6
  • 2017年10月26日 12:32
  • 204

Bootstrap的基本使用方法,5分钟帮你搞懂怎么用

作为Web开发的Coder,是不是很对浏览器兼容性,各种移动设备适配都很头大,所以我们有必要学习一下当下主流的一个Html5框架,即Bootstrap!...
  • CodeByCoder
  • CodeByCoder
  • 2016年03月28日 21:13
  • 34661

5分钟搞懂Android DeepLink

最近碰到了一个新的需求,用户在浏览器中打开分享出去的内容,如果该用户设备上有我们的客户端则打开客户端并且定位到当前文章,如果没有的话则进行下载。调研过程中遇到了不少的坑,这里share一下。先看一下效...
  • u012792689
  • u012792689
  • 2016年12月29日 11:26
  • 7034

5分钟彻底搞懂Border画多边形原理

在网上看到大神用border属性来讲div变成三角形,梯形等等各种形状。也详细解释了原理,我看了半天也弄懂了。接下来这篇我希望能用5分钟让前端小白们毫无压力的彻底理解这个原理,这样以后要用的时候也不懂...
  • Creabine
  • Creabine
  • 2016年07月01日 18:22
  • 1914

Bootstrap的基本使用方法,5分钟帮你搞懂怎么用

原文地址:http://blog.csdn.net/codebycoder/article/details/51001256 作为Coder,我们都接触过Web design,如何快速的构建Web应...
  • gaiyindexingqiu
  • gaiyindexingqiu
  • 2017年05月17日 22:45
  • 905

[zt] 5分钟搞定内存字节对齐

http://blog.csdn.net/hairetz/archive/2009/04/16/4084088.aspx 写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeo...
  • pisheng
  • pisheng
  • 2011年03月17日 07:06
  • 244
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:5分钟搞懂字节对齐
举报原因:
原因补充:

(最多只允许输入30个字)