结构体对齐规则
- 结构体的第一个成员总是存储在结构体变量开辟的空间的起始地址。
- 其它成员变量要存储在一个名叫对齐数的整数倍的地址。
- 不同的编译器有着不同的对齐数,例如Visual Studio Code的编译器的对齐数是8,Linux的编译器的对齐数是4。
- 结构体的对齐数是变量大小和编译器对齐数的比较的较小值,例如在Linux下char变量的对齐数是1,int变量的对齐数是4,char *变量的对齐数是4。
- 结构体总大小为最大对齐数的整数倍,结构体内每一个变量都会产生一个对齐数,取其最大的对齐数。
- 如果是嵌套结构体,那么嵌套的结构体存储在自己成员的最大对齐数的整数倍地址处,嵌套结构体大小为所有成员(包括嵌套的结构体的成员)的最大对齐数的整数倍。
结构体Tmp与结构体Cmd,结构体Msg的变量在内存的存放位置
结构体Tmp,大小为12
结构体Cmd,大小为8
结构体Msg,大小为8
示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Tmp
{
char c1;
int a;
char c2;
};
struct Cmd
{
char c1;
char c2;
int a;
};
struct Msg
{
int a;
char c1;
char c2;
};
int main(int argc,char *argv[])
{
struct Tmp t;
struct Cmd c;
struct Msg m;
memset(&t,0,sizeof(struct Tmp));
memset(&c,0,sizeof(struct Cmd));
memset(&m,0,sizeof(struct Msg));
printf("int size is %ld\n",sizeof(int)); //4
printf("char size is %ld\n",sizeof(char)); //1
printf("int* size is %ld\n",sizeof(int *)); //8
printf("char* size is %ld\n",sizeof(char *)); //8
printf("Tmp struct size is %ld\n",sizeof(struct Tmp)); //12
printf("Tmp struct variable size is %ld\n",sizeof(t)); //12
printf("Cmd struct size is %ld\n",sizeof(struct Cmd)); //8
printf("Cmd struct variable size is %ld\n",sizeof(c)); //8
printf("Msg struct size is %ld\n",sizeof(struct Msg)); //8
printf("Msg struct variable size is %ld\n",sizeof(m)); //8
return 0;
}
嵌套结构体对齐
嵌套结构体Msg1,大小为24
嵌套结构体Msg2,大小为16
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Tmp // size = 16
{
char tc1;
int ta;
char tc2;
int tc3;
};
struct Cmd // size = 8
{
char cc1;
char cc2;
int ca;
};
struct Msg1
{
int a;
char c1;
char c2;
struct Tmp t;
};
struct Msg2
{
int a;
char c1;
char c2;
struct Cmd c;
};
int main(int argc, char *argv[])
{
struct Tmp t;
struct Cmd c;
struct Msg1 m1;
struct Msg2 m2;
memset(&t, 0, sizeof(struct Tmp));
memset(&c, 0, sizeof(struct Cmd));
memset(&m1, 0, sizeof(struct Msg1));
memset(&m2, 0, sizeof(struct Msg2));
printf("Tmp struct size is %ld\n", sizeof(struct Tmp)); // 16
printf("Cmd struct size is %ld\n", sizeof(struct Cmd)); // 8
printf("Msg1 struct size is %ld\n", sizeof(struct Msg1)); // 24
printf("Msg1 struct variable size is %ld\n", sizeof(m1)); // 24
printf("Msg2 struct size is %ld\n", sizeof(struct Msg2)); // 16
printf("Msg2 struct variable size is %ld\n", sizeof(m2)); // 16
return 0;
}