结构体对齐的规则
1.n字节对齐,32位默认n为4,64位默认n位8,(n是结构体内长度最大的数据类型的长度(字节数),)
2.每个变量的对齐规则都是自己的数据类型长度大小
3.总长度是字节对齐数的整数倍
struct s1
{
int a; // 4
char b; // 1+1 ,补1个
short c; // 2
};
typedef struct s2
{ // 1字节对齐 8字节对齐
int a; // 4 4
struct s1 s; // 7 4 1(+1) 2(+4)
double b; // 8 8
int c; // 4 4(+4)
}s2_tyname;
struct s3
{
char ch1; // 1+3
int i; // 4
float j; // 4+4
double k; // 8
};
int main()
{
printf("s1 = %ld\n",sizeof(struct s1));
printf("s2 = %ld\n",sizeof(struct s2));
printf("s2_tyname = %ld\n",sizeof(s2_tyname));
printf("s3 = %ld\n",sizeof(struct s3));
return 0;
}
#pragma pack(n)
#pragma pack(n)有两种用法:
我们需要#prgama pack(n)开头,以#pragma pack()结尾,定义一个区间,这个区间内的对齐参数就是n。
#pragma pack(1)
struct s4
{
char ch1; // 1
int i; // 4
float j; // 4
double k; // 8
};
#pragma pack()
#pragma pack(4)
struct s5
{
char ch1; // 1+3
int i; // 4
float j; // 4
double k; // 8
};
#pragma pack()
#pragma pack(8)
struct s6
{
char ch1; // 1+3
int i; // 4
float j; // 4
double k; // 8
};
#pragma pack()
#pragma pack(16)
struct s7
{
char ch1; // 1+3
int i; // 4
float j; // 4
double k; // 8
};
#pragma pack()
printf("s4 = %ld\n",sizeof(struct s4)); //17
printf("s5 = %ld\n",sizeof(struct s5)); //20
printf("s6 = %ld\n",sizeof(struct s6)); //24
printf("s7 = %ld\n",sizeof(struct s7)); //24
attribute((packed)) 和__attribute__((aligned(n)))
1 :1字节对齐
__attribute__((packed)) :下划线是两个
struct s8
{
char ch1; // 1+3
int i; // 4
float j; // 4
double k; // 8
}__attribute((packed));
sizeof(struct s8)==17;即1字节对齐
2 :n字节对齐
__attribute__((aligned(n))):下划线是两个
struct s11
{
char ch1; // 1+3
int i; // 4
float j; // 4
double k; // 8
}__attribute__((aligned(1024)));
printf("s10 = %ld\n",sizeof(struct s11)); //1024
(1)__attribute__((packed))使用时直接放在要进行内存对齐的类型定义的后面,然后它起作用的范围只有加了这个东西的这一个类型。packed的作用就是取消对齐访问。
(2)__attribute__((aligned(n)))使用时直接放在要进行内存对齐的类型定义的后面,然后它起作用的范围只有加了这个东西的这一个类型。它的作用是让整个结构体变量整体进行n字节对齐(注意是结构体变量整体n字节对齐,而不是结构体内各元素也要n字节对齐)