0%

结构体的内存对齐

Data 16位 32位 64位
char 1 byte 1 byte 1 byte
int 2 bytes 4 bytes 4 bytes
float 4 bytes 4 bytes 4 bytes
double 8 bytes 8 bytes 8 bytes
long 4 bytes 4 bytes 8 bytes
short 2bytes 2bytes

字节对齐的细节和编译器实现相关,一般而言有3个准则。

  1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除。

  2. 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(Internal Adding)。

  3. 结构体的总大小为结构体最大基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(Trailing Padding)。

(1)例1:简单体验

1
2
3
4
5
struct name
{
char b;
int a;
};//内存大小为1+4+3=8由准则3易得,1+4并不是该结构体中最大字节的数据类型(int)的倍数,因此要补3位,如下图

例1:原理图:(这里,编辑器会根据结构体中最大字节的数据类型给内存等分成小段,比如下图中蓝色与绿色的荧光笔就代表着分成了的其中两段

image-20220315135130944

(2)例2:数据类型的顺序对结构体内存大小的影响

1
2
3
4
5
6
struct name
{
char a;
char b;
int c;
};//内存大小为1+1+4(+2)=8,同样是由准则3得到;

例2:原理图

image-20220315135520017

例3:

1
2
3
4
5
6
struct name
{
char a;
short b;
int c;
};

例3原理图:

image-20220315140644830

例4:

1
2
3
4
5
6
struct name
{
char a;
int b;
char c;
};//原理如下图:内存空间为1+4(+3)+1(+3)=12;这是由准则2和3得到的。分配完char和int后所占字节为5不是最大字节的数据类型(int)的整数倍,所以要补位+3,最后一个补位+3同理

例4:原理图:

image-20220315142719809

很显然,数据类型的排列的顺序不同也会影响到结构体的内存空间

例4:

1
2
3
4
5
6
7
struct student
{
char a;
double b;
int c;
};
//原理图如下:内存空间为1+8(+7)+1(+7)=24

例4:原理图

image-20220315143612581

例5:带有数组的结构体

1
2
3
4
5
6
7
struct student
{
char a[10];
double b;
int c;
};//内存大小32字节·

注意:最大的基本类型double b而不是char a[10]

例5:原理图

image-20220128195544671

例6:

1
2
3
4
5
6
struct student
{
int a[9];
double b;
char c;
};//数组

例6:原理图

image-20220128204325287

#pragma pack(n) n为整数

  • n 就相当于上面的最大数据类型的字节