首先定义一个结构体

struct object{

char a;

char b;

int c;

};

 

要求该结构体类型的字节大小,需要了解结构体内存对齐,以下是结构体内存对齐的相关规则:

1)第一个成员变量在与结构体变量偏移量为0的地址处;

2)其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处;

对齐数=编译器默认的一个对齐数与该成员大小的较小值;

规定VS编译器的对齐数默认值为8,gcc无默认对齐数;

3)结构体总体大小为最大对齐数的整数倍;

4)对于嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍;

 

以上就是官方语言给出的规则,这样看是很难看懂的,接下来用一个例子来演示一遍就简单明了了。以文中开始定义的结构体为例:

struct结构体 java struct结构体大小计算_数据

 

 

在下面我们可以验证一下我们的分析是否正确

struct结构体 java struct结构体大小计算_嵌套_02

 

 

由此可见我们的分析是正确的。

如果把原来的结构体

struct object{

char a;

char b;

int c;

};

 

改为

struct object{

char b;

int c;

char a;

};

 

那么该结构体的大小是否还会是8呢?我们画图分析一下:

struct结构体 java struct结构体大小计算_内存空间_03

 

 

由图可发现,该结构体占用了9个内存空间,那么该结构体所占内存大小就是9吗?我们先来验证一下:

struct结构体 java struct结构体大小计算_struct结构体 java_04

 

 

怎么会是12呢?

因为该结构体中最大的数据类型所占的内存空间是4,而9不是4的整数倍,所以在原来所占的9个内存的基础上还要再浪费3个内存空间才可以,所以该结构体所占的内存大小为12。

我们可以发现,尽管结构体中的数据的类型和相同类型的个数也相同的情况下,不同的排列顺序会导致该结构体所占用的内存空间也会有所不同,可以得到一个结论:若要结构体内存占的最小,把内存小的数据类型的数据放在结构体的前面即可。

对于结构体嵌套来说,内存大小的计算仅有一点小小的改变,举个例子:

struct object{

char a;

char b;

int c;

};

由上面的解析我们知道该结构体内存大小为8

struct subject{

Int q;

Struct object w;

char e;

};

对于该结构体来说,内存是多少呢?

我们先来分析一下:

struct结构体 java struct结构体大小计算_数据_05

 

 

 

我们验证一下:

struct结构体 java struct结构体大小计算_数据_06

 

 那么,为什么存在内存对齐呢?

1)平台原因:不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处取某些特定数据类型的数据,否则抛出硬件异常;

2)性能原因:数据结构应尽可能在自然边界对齐,原因在于为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的数据,内存访问只需要一次就够。

总的来说:结构体的内存访问是拿空间来换时间的做法。