结构体大小计算(内存对齐问题和修改默认对齐数)

结构体中如何计算结构体大小呢?那么首先应该理解并掌握结构体的对齐规则,为什么数组中不需要对齐有人会问,这是因为数组中放入的是同类型的数据,比如字符串数组,字符数组,指针数组,数值数组等。而结构体中存放的是不同类型的数据,比如结构体成员列表可为数组,指针,整型,字符型,浮点型等组合。总体来说结构体的内存对齐是拿空间来换取时间的做法,那么在设置结构体时,我们既要满足对齐,又要节省空间如何做到呢?只能让占用空间小的成员尽量集中在一起。那么结构体在对齐方式不合理时我们可以修改默认对齐数。
一.结构体对齐规则:
1.第一个成员在与结构体变量偏移量为0的地址处 。 (第一个成员也有对齐数)
2.其他成员变量要对齐到对齐数的整数倍的地址处。
(对齐指存放该变量时的起始偏移量必须能整除该变量的对齐数,通常是能整除对齐数的最小整数)
对齐数 =编译器默认的一个对齐数与该成员大小的较小值。
(VS中默认为8,Linux中的默认值为4,默认参数只能设置成1,2,4,8,16)
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体 的整体大小就是所有最大对齐数(含有嵌套结构体的对齐数)的整数倍。
(一个结构体的对齐数是结构体中最大的对齐数)
二. 修改默认对齐数
#pragma 这是个预处理指令,可以修改默认对齐数

# include <stdio.h>
# include <stdlib.h>
//# pragma pack(1)
//# pragma pack(2)   //设置默认对齐数为2
//# pragma pack(4)
//# pragma pack(8)
//# pragma pack(16)
struct s1              //结构体
{
	char c1;
	int i;
	char c2;
};
struct s2
{
	char c1;
	char c2;
	int i;
};
struct s3
{
	double c1;
	char c2;
	int i;
};
//#pragma pack()  //取消设置的默认对齐数,还原为默认设置
struct s4
{
	char c1;
	struct s3 s3;
	double d;
};
struct s5
{
	struct s4 s4;
	int e;
	char f[5];
	char* h;
	void(*g)(int);  //空类型指针函数

};
int main ()
{
	printf ("s1=%d\n",sizeof(struct s1));    //输出结构体大小
	printf ("s2=%d\n",sizeof(struct s2));
	printf ("s3=%d\n",sizeof(struct s3));
	printf ("s4=%d\n",sizeof(struct s4));
	printf ("s5%d\n",sizeof(struct s5));
    system ("pause");
    return 0;
}

1.VS默认对齐数运行结果
在这里插入图片描述
2.修改默认对齐数为1运行结果
在这里插入图片描述
3.修改默认对齐数为2的运行结果
在这里插入图片描述
4.修改默认对齐数为4的运行结果
在这里插入图片描述
5.修改默认对齐数为4的运行结果,在s4上面还原默认对齐数
在这里插入图片描述
6.修改默认对齐数为8或16的运行结果 (与VS默认对齐数运行结果一样)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/QLH04_04/article/details/84194919