struct内存对齐
来源:互联网 发布:js调用android和ios 编辑:程序博客网 时间:2024/06/05 02:16
出于速度和空间的考量,编译器在实现过程中均会采用对struct内的变量进行内存对齐的操作,虽然会有一定的空间浪费,却可以减少在读取数据时候的读取操作。
先看下面的例子
struct A{ char a; int b;};int main(){ cout << "size of A:"<<sizeof(A)<<"bytes" << endl; return 0;}输出的结果是8字节。
对于这样的结构体,在内存中有两种存储方式。
|| 1B || 2B || 3B || 4B || 5B || 6B || 7B || 8B ||
1. || a || ------------b----------- ||
2. || a || || ------------b----------- ||
对于第一种存储方案,6、7、8三个字节的存储空间还可以留给后续使用。但注意,当我们要读取b的值的时候,32位的CPU会先读取1-4字节,再读取5-8字节,然后进行拼接得到b的值。而第二种方案,虽然会浪费掉2-4这三个字节,但读取b的值的时候,只需要一次读取操作就可以完成。
了解了内存对齐的基本思想,我又产生了三个新的疑问。一是,内存对齐与结构体内变量声明的顺序是否有关。二是,进行内存对齐的对齐标准是什么,是怎样确定的对齐标准。三是,如果对于64位机器,那么上面的第一种方案无疑是可取的,但实验表明,64位机器上(64位编译器)仍然采取了方案二进行对齐。
对于第一个疑问,看代码:
struct A{ char a,c; int b;};struct B{ char a; int b; char c;};int main(){ cout << "size of A:"<<sizeof(A)<<"bytes" << endl; cout << "size of B:"<<sizeof(B)<<"bytes" << endl; return 0;}输出的结果是A为8字节,B为12字节。这说明,在结构体内声明变量的顺序会影响结构体的内存分配。编译器在处理时,是按顺序进行内存分配和对齐的。
对于疑问二,在别人的博文中(http://blog.csdn.net/kokodudu/article/details/11918219),我看到了一个关于对齐的概念:
这里面有四个概念值:
1)数据类型自身的对齐值:基本数据类型的自身对齐值。
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
4)数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值。
概念看着比较多,但对于我们实际使用来说,可以进行一个简单不精确的概括。首先,平时写代码时,很少会用到指定对齐值,所以不用关注概念2和概念4 。而对于概念1和概念3,可以简单的理解为,结构体会按照其内部所包含的最长的基本类型成员(包括成员结构体的成员)的长度进行对齐。
下面看一个例子。
struct A{ char a[5];};struct B{ A a; int b;};int main(){ cout << "size of A:"<<sizeof(A)<<"bytes" << endl; cout << "size of B:"<<sizeof(B)<<"bytes" << endl; return 0;}输出的结果是A是5字节,B是12字节。
分析起来很简单,因为A中最长的基本数据类型是char,所以按1字节进行对齐。B中最长的基本数据类型是int,所以按4字节进行对齐。
但是这个概念里忽略了几个基本数据类型,枚举、指针。下面我们就来测试一下这几个类型的对齐长度。
enum e{};struct A{ e a;};struct B{ int* a;};int main(){ cout << "size of A:"<<sizeof(A)<<"bytes" << endl; cout << "size of B:"<<sizeof(B)<<"bytes" << endl; return 0;}输出结果对于A,结果是4字节。对于B,32位编译器的结果是4字节,64位编译器的结果是8字节。
对于疑问三,实际上这个疑问是有问题的。因为虽然在一个存取周期内CPU把数据读入了CPU之中(假设读入到寄存器RAX中),我们需要对RAX进行移位操作才能使得EAX寄存器中恰好取得int变量b的值。
最后,概括起来,借用《Windows核心编程》里的话来总结结构体进行对齐的根本原因:当CPU访问正确对齐的数据时,它的运行效率最高,当数据大小的数据模数的内存地址是0时,数据是对齐的。
- struct union 内存对齐
- (Struct)内存对齐
- struct 内存对齐
- struct内存对齐 详解
- union struct 内存对齐
- struct内存对齐
- (Struct)内存对齐
- struct内存对齐
- struct 内存对齐规则
- struct内存对齐
- struct/union内存对齐
- struct内存对齐
- struct内存对齐
- C++ struct内存对齐
- struct内存对齐
- 内存对齐(Struct)
- sizeof union struct 内存对齐
- sizeof union struct 内存对齐
- windows下《七天学会NodeJS》学习笔记之四--网络操作
- 重新认识重构的意义
- 如何安装星际译王
- MFC中的消息映射(Message Mapping)
- Android关于ListView的优化问题
- struct内存对齐
- hadoop面试题
- HDU - 2680 - Choose the best route (经典最短路问题dijkstra算法!!)
- lua中的table函
- 利用Matlab的Simulink原理框图来画bode图的方法
- OpenCV滤波之copyMakeBorder和borderInterpolate
- 新年梦想
- Java基础----序列化问题
- 思科CCNA第一学期第五章答案