转载的一个小程序,学习学习。
align_malloc函数返回的align地址可按任意字节对齐。分配size+align_ment的空间,多分配alignment空间主要是用来调整指针的地址。调整好以后将mem_ptr指针与tmp指针之间的偏移量保存在*(memptr-1)的内存地址处,回收内存时用来找到真正的内存块地址即tmp指针。
i386中堆的分配是向上增长的,而栈则上向下增长。
这里有点不明白,为什么要把这个偏移量保存在*(memptr-1)中,保存在*(memptr-2)或者一个全局指针中应该都可以吧??
我们可以选择保存偏移量,也可以选择保存指向tmp指针的指针。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void * align_malloc(unsigned int size, unsigned int alignment)
{
unsigned char * mem_ptr;
unsigned char * tmp;
if(!alignment) alignment=4; //至少按4对齐
/* Allocate the required size memory + alignment so we
* can realign the data if necessary */
if ((tmp = (unsigned char *) malloc(size + alignment)) != NULL){
/* Align the tmp pointer */
mem_ptr = (unsigned char *) ((unsigned int) (tmp + alignment - 1) & (~(unsigned int) (alignment - 1))); /////////mem_ptr= (unsigned char*)tmp + (alignment - (unsigned long)(tmp) % alignment);也可以按这种方法来调整指针
/* Special case where malloc have already satisfied the alignment
* We must add alignment to mem_ptr because we must store
* (mem_ptr - tmp) in *(mem_ptr-1)
* If we do not add alignment to mem_ptr then *(mem_ptr-1) points
* to a forbidden memory space */
if (mem_ptr == tmp)
mem_ptr += alignment;
/* (mem_ptr - tmp) is stored in *(mem_ptr-1) so we are able to retrieve
* the real malloc block allocated and free it in xvid_free
mem_ptr-1这个内存地址用来存储调整后的mem_ptr与真正的内存分配块之间的偏移量*/
*(mem_ptr - 1) = (unsigned char) (mem_ptr - tmp);
//PRT("Alloc mem addr: 0x%08x, size:% 8d, file:%s <line:%d>, ", tmp, size, file, line);
/**//* Return the aligned pointer */
printf("memptr address is %p\n",mem_ptr);
printf("tmp address is %p\n",tmp);
printf("offset is %d\n",*(mem_ptr -1));
return ((void *)mem_ptr);
}
return(NULL);
}
/**//*****************************************************************************
* align_free
*
* Free a previously 'xvid_malloc' allocated block. Does not free NULL
* references.
*
* Returned value : None.
*
****************************************************************************/
void align_free(void *mem_ptr)
{
unsigned char *ptr;
if (mem_ptr == NULL)
return;
/**//* Aligned pointer */
ptr = (unsigned char *)mem_ptr;
/* *(ptr - 1) holds the offset to the real allocated block
* we sub that offset os we free the real pointer
减去这个偏移值,找到真正的内存分配块地址*/
ptr -= *(ptr - 1);
/**//* Free the memory */
free(ptr);
}
int main()
{
int *ptr;
ptr = (int *)align_malloc(256,24);
printf("address is %p\n",ptr);
printf("value is %d \n",(unsigned int)ptr % 24);
align_free(ptr);
return 0;
}
程序的打印来看,返回的地址的确是按24字节对齐的。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。