struct结构体内存对齐相关知识

内存对齐的意义
结构体中成员按照定义时的顺序依次存储在连续的内存空间。但并不是像数组那样的连续。
内存对齐计算内存地址比较方便,内存地址会非常有规律,减小了内存寻址时间。若不对齐,内存地址的变化非常没有规律。
cpu把内存当成是一块一块的。块的大小可以是2,4,8,16 个字节,因此CPU在读取内存的时候是一块一块进行读取的,块的大小称为(memory granularity)内存读取粒度。

我们再来看看为什么内存不对齐会影响读取速度?

假设CPU要读取一个4字节大小的数据到寄存器中(假设内存读取粒度是4),分两种情况讨论:

1.数据从0号自己开始
2.数据从1号字节开始(内存不对齐)

解析:当数据从0字节开始的时候,直接将0-3四个字节完全读取到寄存器,结算完成了(一遍即可)。
   当数据从1字节开始的时候,问题很复杂,首先先将前4个字节读到寄存器,并再次读取4-7字节的数据进寄存器,接着把0字节,4,6,7字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器,对一个内存未对齐的寄存器进行了这么多额外操作,大大降低了CPU 的性能。

内存对齐原则:
    1、第一个成员的首地址为0.
    2、每个成员的首地址是自身大小的整数倍
    3、结构体的总大小,为其成员中所含最大类型的整数倍。
    4.任何指针在win32情况下都只占4个字节。
    5,空结构体的大小为1.

例子:

以下为64位下的对齐,即最大对齐
在这里插入代struct A
{
	int a; //首地址0 
	double b;//起始地址为8 
	char c;//起始地址为16
	double d;//起始地址为24
	float e;//起始地址为32
	int f;//起始地址为36
};//总大小为40 码片
struct B
{
	short b;//起始为0
	char a;//起始为2
	char c;//起始为3
};//总大小为4 (short类型最长,为short大小的倍数)

以上两个例子为64为下的对齐,即:最大对齐字节为8.
32位下最大对齐字节为4

#pragma pack
以使用#pragma pack来指定内存对齐的方式

在我们上面的两个例子上加上 #pragma pack(4)我们再来看看运行结果。
在这里插入图片描述
struct A 的大小变为了 32
如何理解?因为32为4字节对齐,我们可以把double类型看为两个4字节。
这样就好理解了。

扩展:能否使用memcmp比较两个结构体是否两同

不能用函数memcpy来判断两个结构体是否相等:memcmp函数是逐个字节进行比较的,而struct存在字节对齐,字节对齐时补的字节内容是随机的,会产生垃圾值,所以无法比较。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值