内存对齐
1、小知识
结构体是自定义数据类型
2、为什么会有内存对齐?
是因为终端不同内存对齐不同导致的,例如,pc端和手机就不同。
假如没有内存对齐,当两个主机8b和16b,当16b给8b发送一条信息时,它只会读取前一部分信息,不能被主机所破解其中的含义;反之,16b解析8b时,主机虽然读完了接收的信息,但是多读了8b乱码,当解析时并不能破解其中的含义,这样就会导致计算机崩溃。
3、含义
内存对齐简单说就是,结构体成员存放地址要能整除成员本身的大小。
(牺牲一点空间,换取较快的运行速度)
4、用法
(1)前面所有成员大小相加应是当前成员大小的倍数;
(2)整个结构体的大小应该是整除该结构体中单个最大成员大小的倍数。
5、下面来看几个例子,加深一下记忆。
例1:
struct A
{
char a;//1+3
int b;//4
}//8
char加int应该是5个字节(5B),整个结构体应该是5B,但是根据用法一,可以发现,5并不是4的倍数,所以应该是8,在根据用法二,单个最大成员大小为int(4B),发现8合理,故,该结构体大小为8B。
例2:
struct B
{
char a;//1+1
short b;//2
int c;//4
}//8
根据例1,我觉得该结构体是12B,但是错了,根据用法一,先看char和short,按照例1的方法,应该是4B,在看int,应该是8B,在根据用法二,单个最大成员大小为int(4B),发现合理,故,该结构体大小为8B。
例3~6:
//例3
struct C
{
int a;//4
char b;//1+1
short c;//2
};//8
//例4
struct D
{
char a;//1+3
int b;//4
short c;//2+2
};//12
//例5
struct E
{
int a;//4+4
double b;//8
float c;//4+4
};//24
//例6
struct F
{
int a;//4
float b;//4
double c;//8
};//16
在这几个例子中,还需回到内存对齐的根本,结构体成员存放地址要能整除成员本身的大小,故,应考虑结构体数组,而不是单个结构体内存,要保证结构体数组中每个成员都符合内存对齐的条件。
例7~9:
//例7
struct AA
{
char a;//1
struct a
{
int b;
long c;
}d;//声明并定义了变量
};//12
//例8
struct BB
{
char a;//1+3
struct b
{
int b;//4
long c;//4
};//声明并未定义变量
};//1
//例9
struct CC
{
char a;//1+3
struct
{
int b;//4
long c;//4
};//声明并定义了一个没有名字的变量
};//12
本题中为嵌套结构体,它的结构体大小取决于内部结构体是否被定义成变量,若定义了,就需考虑,否则,直接忽略,仅仅计算除内部结构体以外的变量内存大小。
例9:
struct G
{
char a;//1+1
short b[4];//2*4=8
int c;//4
};//14+2
本题中最主要的是short类型的数组,不能因为该数组大小为8B,就将char加7,这是错误的,应该看数组类型的大小,应该给char加1,该结构体大小为14B,根据用法二,单个最大成员大小为int(4B),故,结构体大小为16B。
6、以上例子都是根据用法一、二来进行分析得到结构体大小的。可是,如何解决内存对齐方式不同呢?
#pragma pack(1)
“(n)”中的数字代表,以n(B)对齐
此方法解决了对齐方式不同而导致的乱码情况。
7、总结
这也是以后工作中最常用的方法,希望大家都和我一样好好掌握。