大部分的参考资料都是如是说的:
ios
一、平台缘由(移植缘由):不是全部的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,不然抛出硬件异常。
二、性能缘由:数据结构(尤为是栈)应该尽量地在天然边界上对齐。缘由在于,为了访问未对齐的内存,处理器须要做两次内存访问;而对齐的内存访问仅须要一次访问。数据结构
#include <stdlib.h> #include <iostream> using namespace std; int main() { struct AA { char a; char b; char c; }; cout << sizeof(AA) << endl; system("pause"); }
这个比较简单,能够根据上面的表格能够直接计算出来。性能
来个有点难度的spa
#include <stdlib.h> #include <iostream> using namespace std; int main() { struct AA { char a; int b; char c; }; cout << sizeof(AA) << endl; system("pause"); }
猜猜结果会是多少? 会是 5 吗??3d
来详细了解一下:code
实际上会如图所示吗???blog
当以如图的方式存放数据时,系统访问char a 时,只需读取一个字节,但当访问 int b 的时候,先要读取一个字节,在读取四个字节,才能读到int b的值。这样系统在访问数据时要先判断各个数据的字节大小,在进行读取,这样就会浪费时间。为了节省时间,会以下的方式去存储数据:内存
在存储数据时,会对char a 补充 3 个字节,这样在访问 char a、int b 时,每次只需读取 4 个字节就能够,以一种空间换时间方式来提升效率。编译器
当如图存放数据以后,整个结构体的大小为 9 个字节。这与计算输出的结果不符(还记得,经过程序计算的大小为 12 个字节),这是为何吗??io
还记得前面说的内存对齐的第四条规则吗??
4.结构体总大小必须是对齐模数的整数倍。
在上面给出了一个表格,上面有常见数据类型的模数,那咱们如何肯定一个结构提的模数呢???
其实结构体的模数等于其内部模数最大的成员类型的模数
struct AA { char a; int b; char c; };
对于结构体AA来讲,他的模数就是 4。
则该结构体的大小必须是 4 的整数倍,因此在最后还会补充 3 个字节(以下图)。
这样结构体AA的大小就是 12 个字节。
#include <stdlib.h> #include <iostream> using namespace std; int main() { struct AA { char a; int b; char c; }; struct BB { char d; int e; double f; AA g; }; cout << sizeof(BB) << endl; system("pause"); }
先来看看答案:
来分析一下:
到结构AA,来看看结构体AA的状况:
因此接下来应该以下图:
由图可知 结构体BB一共占据32个字节的内存,到这里就完了吗??
还记得 内存对齐的第四条规则吗??
4.结构体总大小必须是对齐模数的整数倍。
结构体BB的模数为多少呢??
由于double e 的模数最大为 8 ,因此BB的模数也为8。32 是 8 的倍数,因此结构体BB只占 32 个字节。
能够经过#pragma pack() 自定义模数的大小。
#include <stdlib.h> #include <iostream> using namespace std; #pragma pack(1) int main() { struct AA { char a; int b; char c; }; struct BB { char d; int e; double f; AA g; }; cout << sizeof(BB) << endl; system("pause"); }
将模数的大小自定义为 1 后,运行结果以下:
当模数大小定义为 2 时,运行结果以下:
能够本身去试试画图理解。