关于结构体的字节对齐是什么,就不赘述,再此附上一篇文章,介绍字节对齐:http://www.linuxsong.org/2010/09/c-byte-alignment/

这里的结构体字节对齐的数据类型都是基本数据类型,如果结构体的定义中含有结构体成员呢?

网上有很多人写博客谈到这个问题,都认为该结构体成员应该被看做一个整体,按照整体的字节数来进行字节对齐,选择首地址。但是经过测试,这种说法是不对的。

 struct s1{
char c1;
char c2;
char c3;
char c4;
}; struct s2{
char a;
struct s1 s;
};

对于上述代码,显然sizeof(struct s1) = 4。如果将struct s1看做整体,来进行字节对齐的话,sizeof(struct s2)应该是等于8。但是该段代码在gcc和VS2010下测试的结果都是5。

所以,s2的内存布局如下

s2 : char | char char char char |

s的首地址并非为4,而是char类型长度的整数倍

同样,对于结构体:

 struct S1
{
char a;
short b;
}; struct S2
{
char a;
struct S1 s;
};

上述代码中,sizeof(struct S1) = 4,而sizeof(struct S2) = 6。

S2的内存布局是:

S2 : char **** | char **** short short

s的首地址并非为4,而是short类型长度的整数倍,结构体S2的长度并非结构体S1长度的整数倍,而是short类型长度的整数倍

相对的,我们可以看一下结构体:

struct S
{
char a;
char b;
short c;
};

sizeof(S) = 4。

其内存布局为:

S : char char short short

对比S2和S,我们看到,S2中的s结构体成员确实是仍按它作为S1结构体的整体(占用4个字节)来布局的。

那么我们可以得出这情形下的字节对齐问题的结论:

1)结构体中的结构体成员,是按照原结构体的内存布局在新结构体中进行布局的;

2)结构体中的结构体成员,其内存首地址为该成员中最长数据类型的整数倍;

3)结构体的整体长度与其中的结构体成员无关,而是整个结构体(包括结构体成员内部)中的最长数据类型的整数倍。

得出结论后,我们回到处理器本身,来探讨一下编译器之所以这么处理的原因。

从CPU结构角度看内存对齐有一篇比较易懂的文章:

http://hi.baidu.com/maikeai/item/4976f24cc0f905d3c1a592a0

从该文章中,我们可以知道,之所以需要内存对齐,是CPU为了读取数据时减少读取存储器的次数,提高效率。

对于32位的CPU,一次最多读入双字的32位数据,而对于超过32位的数据,在32位的计算机上,就必须多次读取存储器,这与是否字节对齐无关。

我们可以看到,字节对齐,其实实质上是在拿存储器的空间,换CPU的时间。

所以,对于C语言内置的数据类型,可以很好地通过内存对齐来节省时间,同时其浪费的存储器空间也是可控的。

但是,对于结构体成员来说,因为它的长度是不可控的,所以如果强行按整体内存对齐,首先可能因为长度过长,即使内存对齐需要的存储器读取次数也很多,导致优化的时间不明显,另外,也可能导致浪费的存储器空间太大。所以,最简单的平衡空间和时间的方法,就是按照该结构体成员中最长数据类型来进行字节对齐,这样最有可能减少存储器读取次数,也使浪费的存储器空间可控。

最新文章

  1. Unit Testing with NSubstitute
  2. LR接口测试手工脚本与验证脚本
  3. 直接拿来用!最火的Android开源项目
  4. (传输层)TCP协议
  5. c语言的数学函数ceil、floor、round
  6. 解决mysql数据库连接问题
  7. 通用的linux下安装配置svn独立服务
  8. dx中纹理相关的接口备注
  9. Hybrid----优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案-备
  10. pygame编写贪吃蛇
  11. POJ1221(整数划分)
  12. gitignore文件中添加新过滤文件,但是此文件已经提交,如何解决?
  13. javaWeb学习总结(11)- 监听器(Listener)学习
  14. sizzle选择器的使用
  15. alpha冲刺9/10
  16. USB2.0学习笔记连载(一):CY7C68013特性简介
  17. IPv6技术详解:基本概念、应用现状、技术实践(上篇)
  18. difference among String,StringBuilder,StringBuffer
  19. Leetcode 题解 Jump Game
  20. Matlab实现BP网络识别字母

热门文章

  1. EF6 Codefirst+MySql 数据库迁移
  2. ArrayList和LinkedList区别
  3. yum mysql
  4. python基础:测量python代码的运行时间
  5. centOs下的php+mysql+apache+ftp配置
  6. 前端开发面试题收集 JS
  7. [Python]从豆瓣电影批量获取看过这部电影的用户列表
  8. webstrom 常用快捷键
  9. aix5.1 5.2 5.3 6.1 7.1运维技术总结
  10. 利用ItextPdf、core-renderer-R8 来生成PDF