结构体字节对齐

说明

​ 不同类型的数据在内存中按照一定的顺序排列,不一定是顺序的一个一个接着排列

​ 常见的我们定义结构体,结构体大小就不仅仅是每个成员占用大小之和

为什么需要内存对齐

​ CPU对内存的读取不是连续的,而是分块读取的,块的大小只能是 1、2、4、8 、16字节

​ 当读取操作的数据未对齐,则需要两次总线周期来访问内存,因此性能会降低

​ 某些硬件平台只能从规定的相对地址处读取特定类型的数据,否则产生硬件异常

根据对齐参数计算结构体占用大小

​ 规则是:

  1. 第一个成员处于0偏移处

  2. 每个成员按照其类型大小和pack参数中较小的一个进行对齐

    偏移地址必须能被对齐参数整除

    结构体成员类型大小取其内部长度最大的数据成员作为其大小

  3. 结构体成员必须为所有对齐参数的整数倍

  4. 默认的pack参数是4

例子1

#include <stdio.h>
//默认pack对齐参数为4
struct Test1
{				//	 对齐参数   起始地址  占用大小
    char  c1;	//   	1         0        1
    short s;	//		2		  2	       2 
    char  c2;	//		1         4        1 
    int   i;	//      4         8        4
};
//综上 Test1大小为 12

struct Test2
{				//	 对齐参数		起始地址		占用大小
    char  c1;	//		1   		 0				1	
    char  c2;	//		1			 1				1
    short s;	//		2			 2				2
    int   i;	//		4			 4				4
};
//综上 Test2 8


int main()
{
    printf("sizeof(Test1) = %d\n", sizeof(struct Test1));
    printf("sizeof(Test2) = %d\n", sizeof(struct Test2));

    return 0;
}

例子2 带结构体

//默认pack 是 4
struct S1
{               //对齐参数  偏移地址    占用大小
    short a;    //  2       0           2
    long b;     //  4       4           4
};

//综上struct S1 大小为8
struct S2
{                  //对齐参数   偏移地址    占用大小
    char c;        //   1       0           1
    struct S1 d;   //   4       4           8
    double e;      //   4       12          8
};
//综上struct S1 大小为20

int main()
{
    printf("%d\n", sizeof(struct S1));
    printf("%d\n", sizeof(struct S2));

    return 0;
}

更改默认的pack参数

使用#pragma pack(1) 来实现

还是上面的第一个例子

#include <stdio.h>
//默认pack对齐参数为4
#pragma pack(1)
struct Test1
{				//	 对齐参数   起始地址  占用大小
    char  c1;	//   	1         0        1
    short s;	//		1		  1	       2 
    char  c2;	//		1         3        1 
    int   i;	//      1         4        4
};
#pragma pack()
//综上 Test1大小为 8
#pragma pack(2)
struct Test2
{				//	 对齐参数		起始地址		占用大小
    char  c1;	//		1   		 0				1	
    char  c2;	//		1			 1				1
    short s;	//		2			 2				2
    int   i;	//		2			 4				4
};
#pragma pack() 
//综上 Test2 8


int main()
{
    printf("sizeof(Test1) = %d\n", sizeof(struct Test1));
    printf("sizeof(Test2) = %d\n", sizeof(struct Test2));

    return 0;
}

posted @ 2021-05-05 21:53  make_wheels  阅读(126)  评论(0编辑  收藏  举报