结构体内存对齐

结构体内存对齐的规则

结构体内存对齐的计算

内存对齐存在的意义

修改默认对齐数

(一)结构体内存对齐的规则
1.第一个成员在与结构体偏移量为0的地址处
2.其他成员变量要对其到某个数字的整数倍的地址处
注意:对齐数=编译器默认的一个对齐数与该成员大小的较小值
3.结构体总大小为最大对齐数的整数倍
4.如果嵌套了结构体的情况下,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的总大小就是所以最大对齐数(含嵌套结构体的对齐数)的整数倍
(二)结构体内存对齐的计算
1.单个结构体内存对齐

#include<stdio.h>
#include<stddef.h>
struct S1
{
	char a;
	int b;
	char c;
};
int main()
{
	struct S1 s;
	printf("%d\n", sizeof(s));
	printf("%d\n", offsetof(struct S1,a));
	printf("%d\n", offsetof(struct S1, b));
	printf("%d\n", offsetof(struct S1, c));
	return 0;
}

结果为:
在这里插入图片描述
以上计算的依次是结构体所占内存大小和各个成员与结构体首地址的偏移量
各个成员在内存中具体占据空间的情况如图:
在这里插入图片描述
VS系统中默认的对齐数是8
第一个成员占据偏移量为0的位置
第二个成员是int型。占据四个字节的大小,将4与8比较下,4较小,所以第二个成员从偏移量为4的倍数处开始占据内存,即从偏移量为4处开始
第三个成员为char类型,占据一个字节的大小,1与8比较1较小,所以从1的整数倍处开始,即向后占据一个内存
在所有成员中,最大为4个字节,所以结构体的总大小需是4的整数倍,即12个字节
补充:
offsetof为计算结构体成员变量的对齐数,使用方法为:
offsetof(结构体类型名,结构体变量)
使用前需要加上#include<stddef.h>
2.结构体嵌套的内存对齐计算方法

struct S1
{
	double a;
	char b;
	int c;
};
struct S2
{
    int d;
    struct S1 e;
	char f;
};
int main()
{
	
	printf("%d\n", sizeof(struct S2));
	return 0;
}

我们先计算S1的大小
在这里插入图片描述
由上述计算方法可以算得S1所占内存大小为16个字节
接下来计算S2的大小
在这里插入图片描述
开始时d占据偏移量为0的内存,因为在结构体S1中所占最大为8,所以该结构体在偏移量为8的整数倍处开始存储内存,其占据16个字节,然后f向后占据一个字节,因为在两个结构体中所占内存最大为8个字节,所以S2的总大小为8的整数倍,所以结果为32
注:1.在嵌套结构体内存对齐中,嵌套的结构体要看其内部成员变量的大小来决定从偏移量为多少处开始
2.最终的大小要根据两个结构体中的成员变量的最大值,而不是将嵌套在内的结构体看成一个整体
(三)内存对齐存在的意义
1.平台原因:
不是所有硬件平台都能访问任意地址上的任意数字;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
2.性能原因:
数据结构应该尽可能的在自然边界对齐。原因在于,为了访问未对对齐的内存,处理器需要作两次内存访问;而对齐的访问仅需要一次
(四)修改默认对齐数

#pragma pack(8)//设置默认对齐数为8
struct S1
{
	double a;
	char b;
	int c;
};
#pragma pack()//取消设置默认对齐数
  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值