结构体内存对齐方式需要同时满足数据内存对齐与结构体整体内存对齐两个限制要求。
目录
一.数据内存对齐
二.结构体整体内存对齐
三.示例解说(以64位机器为例)
四.带结构体类型的结构体
一.数据内存对齐
数据内存对齐数 = min(数据所占字节数,默认对齐数)。
默认对齐数是编译器所规定的。在32位机器下是4字节,64位机器下是8字节。
各常用类型数据对齐数如下:
数据类型 | 32位机器 | 64位机器 | ||||
数据大小 | 默认对齐数 | 数据对齐数 | 数据大小 | 默认对齐数 | 数据对齐数 | |
char | 1 | 4 | 1 | 1 | 8 | 1 |
short | 2 | 4 | 2 | 2 | 8 | 2 |
int | 4 | 4 | 4 | 4 | 8 | 4 |
char* | 4 | 4 | 4 | 8 | 8 | 8 |
float | 4 | 4 | 4 | 4 | 8 | 4 |
double | 8 | 4 | 4 | 8 | 8 | 8 |
二.结构体整体内存对齐
结构体整体内存对齐数 = min(最大数据类型字节,默认对齐数)
最大数据类型字节就是这个结构体中所有数据类型中所占字节最大的类型。
默认对齐数与前文一致,32位下是4字节、64位下是8字节。
三.示例解说(以64位机器为例)
struct test
{
int a;
char b;
int c;
char* d;
double e;
char f;
}
首先我们找到每个成员的大小与对齐数:
struct test
{
int a;//4,对齐数:4
char b;//1,对齐数:1
int c;//4,对齐数:4
char* d;//8,对齐数:8
double e;//8,对齐数:8
char f;//1,对齐数:1
}
将数据依次合并,判断是否能整除当前数据的内存对齐数:
struct test
{
int a;//4
char b;//4 + 1 = 5
int c;//5 + 4 = 9,9不能整除int默认对齐数4,因此加到12
char* d;//12 + 8 = 20,20不能整除8,因此补到24
double e;//24 + 8 = 32
char f;//32 + 1 = 33
}
再判断所计算总体大小是否能整除整体内存对齐数:
struct test
{
int a;
char b;
int c;
char* d;
double e;//结构体中最大数据类型,8字节
char f;//整体对齐数 = min(8, 8) = 8,33不能整除8,因此补到40
}
四.带结构体类型的结构体
结构体作为成员时的对齐数是他内部成员数据类型中对齐数最大的那一个。
以上述代码为例:
struct test
{
int a;//对齐数4
char b;//1
int c;//4
char* d;//8
double e;//8
char f;//1
}
test结构体作成员时的对齐数就是8,因为test成员中double/char*的对齐数最大是8。
同样结合示例做演示:
struct testb
{
char a;
test b;
int* c;
};
先计算每个成员的大小与对齐数:
struct testb
{
char a;//1,对齐数:1
test b;//40,对齐数:8
int* c;//8,对齐数:8
};
再将数据依次合并,判断是否整除当前数据内存对齐数:
struct testb
{
char a;//1
test b;//1 + 40 = 41,不能整除8,因此补到48
int* c;//48 + 8 = 56
};
再判断能否整除结构体整体对齐数:
struct testb
{
char a;
test b;
int* c;//结构体整体对齐数 = min(8, 8) = 8, 56能整除8, 因此56
};
所有的程序员都是编剧,所有的计算机都是烂演员——Anonymous Hack Actor
如有错误,敬请斧正