C语言 内存对齐
2022-04-27 本文已影响0人
付凯强
引言
先看一个例子:
typedef struct Test
{
char a1;
int a2;
}Test_T;
请问Test_T占几个字节?
如果你的回复是 1 + 4 = 5,那就错了。
我们看下程序运行的结果:
Test_T T;
printf("\nsizeof(T) = %lu\n", sizeof(Test_T));
printf("a1地址:%p\n", &T.a1);
printf("a2地址:%p\n", &T.a2);
sizeof(T) = 8
a1地址:0x7ffd65f12e40
a2地址:0x7ffd65f12e44
程序给出的答案是8个字节。
内存对齐
所谓内存对齐指的是对占用内存较少的类型变量进行内存补齐,对齐占用内存较多的类型变量。在引言中,当char和int放在一起的时候,char自动补齐为4个字节,int占用也是4个字节,加起来就是8个字节。
按照这个理论,那么char和short放在一起,那应该是char自动补齐为2个字节,short两个字节,加起来一共是4个字节。
typedef struct Test
{
char a1;
short a2;
}Test_T;
sizeof(T) = 4
a1地址:0x7ffe4138e454
a2地址:0x7ffe4138e456
再看一个例子,把char和long放在一起,那么char自动补齐为8个字节,long是8个字节,加起来是16个字节。
typedef struct Test
{
char a1;
long a2;
}Test_T;
sizeof(T) = 16
a1地址:0x7fffb1c08ea0
a2地址:0x7fffb1c08ea8
通过示例证明以上结论是正确的。
以上示例都是两个变量,那再加一个变量呢?
typedef struct Test
{
char a1;
int a2;
char a3;
}Test_T;
sizeof(T) = 12
a1地址:0x7fff4e115adc
a2地址:0x7fff4e115ae0
a3地址:0x7fff4e115ae4
依然证明结论是正确的,编译器为char a3补齐了4个字节的存储空间。
那再加一个char变量呢?
typedef struct Test
{
char a1;
int a2;
char a3;
char a4;
}Test_T;
sizeof(T) = 12
a1地址:0x7fffa28395ac
a2地址:0x7fffa28395b0
a3地址:0x7fffa28395b4
a4地址:0x7fffa28395b5
你会发现依然是12个字节,按照上面的结论不应该为char a4补齐4个字节的存储空间吗?答案是当a3和a4可以共用4个字节的存储空间的时候,就只会补齐1份4个字节的存储空间。再写一个示例验证下:
typedef struct Test
{
char a1;
int a2;
char a3;
char a4;
char a5;
char a6;
}Test_T;
sizeof(T) = 12
a1地址:0x7ffd38933d9c
a2地址:0x7ffd38933da0
a3地址:0x7ffd38933da4
a4地址:0x7ffd38933da5
a5地址:0x7ffd38933da6
a6地址:0x7ffd38933da7
会发现a3 a4 a5 a6共享一份1个字节的存储空间。
typedef struct Test
{
char a1;
int a2;
char a3;
char a4;
char a5;
char a6;
char a7;
}Test_T;
sizeof(T) = 16
a1地址:0x7fffe2ebd7f0
a2地址:0x7fffe2ebd7f4
a3地址:0x7fffe2ebd7f8
a4地址:0x7fffe2ebd7f9
a5地址:0x7fffe2ebd7fa
a6地址:0x7fffe2ebd7fb
a7地址:0x7fffe2ebd7fc
会发现单独为char a7补齐了4个字节的存储空间。
总结
typedef struct Test
{
char a1;
int a2;
char a3;
short a4;
}Test_T;
sizeof(T) = 12
a1地址:0x7fff5d3488fc
a2地址:0x7fff5d348900
a3地址:0x7fff5d348904
a4地址:0x7fff5d348906
编译器会为char a1补齐4个字节的存储空间,会为char a3 、short a4补齐4个字节的存储空间。
所谓补齐,并非是变量真正占用,而是为程序多申请了内存空间。如下图所示
内存对齐.png
可以看到:a1只占用一个字节,为了内存对齐保留了三个空白字节;a3和a4加起来共3字节,为了内存对齐保留了1个空白字节。其实这就是空间换时间的一种思想运用。