C语言分配n字节对齐内存地址

需求:

分配一段长度为BUFFER_SIZE个字节的内存,首地址要求n字节对齐

分析:

这个问题的关键是要求首地址按照n字节对齐。为了方便分析,我们以8字节对齐为例

也就是当初始首地址给定为(0,8]之间,我们要将首地址调整到8字节处;当初始首地址在(8,16]之间,我们要将首地址调整到16字节处.....依此类推。总而言之,就是右对齐,与内存地址的增长方向相同。

 

方案:

为了确定首地址,封装了一个宏,如下:

#define ADDR_ALIGN_BASE       8
#define ADDR_ALIGNED(addr)  (((addr) + ADDR_ALIGN_BASE - 1) & (0xfffffff8))

输入addr是一个随意给定的地址,返回一个8字节对齐(右对齐)的地址

总共分为两步:

  • 将给定地址加上(8-1)字节,得到一个新地址
  • 将新地址和0xfffffff8相与,得到最终的8字节对齐的地址

先解释几个问题:

1.为什么是加上,而不是减去;为什么加上的是7个字节,而不是8字节呢?

加上是和内存的增长方向相同,以避免覆盖掉之前的数据(在此默认给定的addr地址之前的内存空间已经使用,addr地址之后的空间没有使用)

加上7个字节是为了避免空间浪费。举一个极端的例子,比如给定的地址就是8字节处,已经对齐,如果加上8个字节的话最终得到的对齐地址就是16字节处,虽然说也是基于8字节对齐,但是8-16字节处的空间浪费掉了。

2.为什么要和0xfffffff8与?

0xfffffff8转换成二进制就是11111111111111111111111111111000,也就是后面跟着三个零,2的3次方正好是8。最终目的就是得到一个能被8整除的地址。

举例:

为了方便理解,举两个例子说明

1.给定地址为7字节处,要求转换为8字节对齐的地址

第一步,7+(8-1) = 14(0x0000000e)

第二步,(0x0000000e)&(0xfffffff8)= 8

结果为8字节处

2.给定地址为9字节处,要求转换为8字节对齐的地址

第一步,9+(8-1) = 16(0x00000010)

第二步,(0x00000010)&(0xfffffff8)= 0x10(16)

结果为16字节处

 

 

ref:

http://www.manongjc.com/detail/10-hgdukjoorgrtexk.html

https://www.jianshu.com/p/eb497ea3f551

https://baijiahao.baidu.com/s?id=1642532556639906097&wfr=spider&for=pc

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值