假设结构体如下:(64bit程序中实例)
struct {
char c; //1*8
double d; //8*2
int i; //4*5
long l; //4*6
} s;
首先各基本数据类型所占字节为:char(1)、double(8)、int(4)、long(4)
-
先查找结构体中最长的字节为对齐长度,这里是double(8)
-
那么按照顺序c(char)先进内存此时内存结构:
c |
---|
- 然后就是填入d(double),因为数据类型都是整数倍,第一行的8个内存已经被占用了一个,那就只能从第二行开始填入内存;剩余第一行的内存做对齐处理。此时内存如下:
c | * | * | * | * | * | * | * |
---|---|---|---|---|---|---|---|
d | d | d | d | d | d | d | d |
- 填入i(int),此时内存空间前16个字节被占用,内存如下:
c | * | * | * | * | * | * | * |
---|---|---|---|---|---|---|---|
d | d | d | d | d | d | d | d |
i | i | i | i |
- 再填入l(long),可以看到第三行刚好可以填入4个字节(long),那么就不需要填入对齐字符。
c | * | * | * | * | * | * | * |
---|---|---|---|---|---|---|---|
d | d | d | d | d | d | d | d |
i | i | i | i | l | l | l | l |
最终结构体长度就是24byte
再修改一下结构体的成员如下:
struct {
char c; //1*8
double d; //8*2
int i; //4*5
double d2; //新增成员
long l; //4*6
} s;
那么此时的内存结构图:
c | * | * | * | * | * | * | * |
---|---|---|---|---|---|---|---|
d | d | d | d | d | d | d | d |
i | i | i | i | * | * | * | * |
d2 | d2 | d2 | d2 | d2 | d2 | d2 | d2 |
l | l | l | l | * | * | * | * |
此时大小为:40byte
总结:
-
内存对齐是以内存占用最长的基本数据类型作为对齐单位的,且对齐后的总大小是最长字节的倍数。
-
数据结构的各类型数据的顺序也会影响内存占用大小,所以一般顺序都是从小->大的顺序进行结构体成员添加,这样就可以节省内存空间了。(相邻的成员类型占用长度不要多大,如(char -> double就浪费了7个字节))