关于Malloc字节对齐的思考

前言:

       1 若变量var要以2的N次幂对齐,以16 byte对齐为例,我们知道16= 0x10,那么16byte对齐的数值必须符合bit0~3均为0的规律,例如32=0x20,48=0x30等;

那么给定一个随机数,如何来达到bit0~3均为0的效果呢,var &~0x0f即可。同理,若需32byte对齐,先看32byte的十六进制对应是什么,32=0x20,bit0~bit4需要全为0。达到32byte对齐需要var &~0x1f才行。依次类推应该可以得出一个更通用的结论,若变量var需要以align byte(为2的N次幂)对齐,可以对当前数值var & ~(align -1)即能达到目的。

2 这里又有个问题,如何实现任意字节的对齐呢?假设数值366,我就是想让他变成199的整数倍,366 - 366%199 = 199就能达到目的。那么想让他变成199*2 =398呢,388+199 - 388%199 = 398就达到了目的。

        3 cpu能访问的地址,一般都会要求至少4 byte对齐,所以没有2当中提到的可能性。


情景:

     基于ANSI的malloc/free实现align_malloc/align_free函数,实现2的N次幂字节对齐,假设要求64byte对齐。实现该项的重点就是要保存base_addr,这样才能正确的free掉分配的区域,防止内存泄露。测试代码如下:

   有一种特殊情形,就是当base_ptr本身已经对齐的情况下,仍然将base_ptr往上加align_bytes,已达到兼容性。

#include <stdio.h>
#include <stdlib.h>


void *align_ptr_malloc(int size,int align_bytes)
{
	void *base_ptr = NULL;
	void *mem_ptr = NULL;


	base_ptr = malloc(size + align_bytes);//alloc alignbytes, rather than align_bytes-1, because we need to store offset
		
	mem_ptr = (void *)((int)((int *)base_ptr + align_bytes -1) & ~(align_bytes-1));
	if(mem_ptr == base_ptr)//base_ptr already align_bytes align
	{
		mem_ptr = base_ptr + align_bytes;//force move it to one more  alignbytes 
	}
	*((int *)mem_ptr-1) = mem_ptr - base_ptr;
	printf("offset is %d base prt %x mem_ptr %x\n",*((int *)mem_ptr -1),base_ptr,mem_ptr);
	return mem_ptr;
}


void *align_ptr_free(void *ptr)
{
	void *base_addr = NULL;
	printf("%x %x\n",ptr,*((int *)ptr - 1));
	base_addr = (void *)(ptr- *((int *)ptr-1));
	printf("ptr %x base_addr %x\n",ptr,base_addr);
	free(base_addr);
}


void main()
{
	void *ptr;
	ptr = align_ptr_malloc(1024,64);
	printf("ptr %x\n",ptr);
	align_ptr_free(ptr);	
}





   


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值