简单的malloc:
int *mallocedMemory = (int *)malloc(1024+15);//这里的15是作为padding出现的这个例子中是1024的话刚刚好可以分为16,但如果
是类似1025~1039这种区间的话就更需要这种padding,以避免每16位分着分着分到其他内存中去。
alignedMemory = (int *)(((int)mallocedMemory + 15) & ~15);//所以是先加padding,再进行对齐。
((void **)alignedMemory)[-1] = mallocedMemory;//没有试但感觉会内存泄漏,还是用*(((void **)alignedMemory)-1)更好。
return alignedMemory;
OGRE的malloc:
void* AlignedMemory::allocate(size_t size, size_t alignment)
{
assert(0 < alignment && alignment <= 128 && Bitwise::isPO2(alignment));
unsigned char* p = new unsigned char[size + alignment];
size_t offset = alignment - (size_t(p) & (alignment-1));
unsigned char* result = p + offset;
result[-1] = (unsigned char)offset;
return result;
}
void* AlignedMemory::allocate(size_t size)
{
return allocate(size, OGRE_SIMD_ALIGNMENT);
}
void AlignedMemory::deallocate(void* p)
{
if (p)
{
unsigned char* mem = (unsigned char*)p;
mem = mem - mem[-1];
delete [] mem;
}
}
这里能看出,数据域之前有offset和padding和-1位,地址偏移量一般指的就是padding和-1位。
x264的malloc:
void *x264_malloc(int i_size){
//memalign等省略。
uint8_t * buf;
uint8_t * align_buf;
buf = (uint8_t *) malloc( i_size + 15 + sizeof( void ** ) + sizeof( int ) );
align_buf = buf + 15 + sizeof( void ** ) + sizeof( int );//这里是在&~15对齐操作之前加上偏移量的位置,这个偏移量记
录了buf指针和一个int类型。
align_buf -= (long) align_buf & 15;//相当于&~操作,也就是对齐。
*( (void **) ( align_buf - sizeof( void ** ) ) ) = buf;
*( (int *) ( align_buf - sizeof( void ** ) - sizeof( int ) ) ) = i_size;
return align_buf;//int应该是用来存储i_size大小(?),void **是buf指向内存地址,再是分配的i_size内存。
}//x264这样写的意义大概就是align_buf在buf的基础上控制16位对齐。
void x264_free(void *p){
if(p){
free(*(((void**)p)-1));
}
}
2^n字节对齐的malloc:https://blog.csdn.net/liujianfei526/article/details/53032713
void* aligned_malloc(size_t size, size_t alignd_byte)
{
//offset地址偏移量(byte)
//alignd_byte对齐字节的预分配空间
//sizeof(void *)保存真实指针的预分配空间
size_t offset = sizeof(void *) + alignd_byte - 1;
//预分配更大的内存块
//q指向这块内存的首地址
void* q = malloc(size + offset);
if (!q)
return NULL;
//printf("q = 0x%p\n", q);
//对齐后的内存块
//不管怎样q指针都向后偏移,再& ~(alignd_byte - 1)地址对齐
//如果是任意字节对齐的话这个偏移计算方法要换
void* p = (void *)(((size_t)(q)+offset) & ~(alignd_byte - 1));
//为了配合free函数,保存q指针到p-1的位置
//p[-1] = q;直接这样做不行void *大小未知无法寻址
*(((void **)p) - 1) = q;
//返回对齐后的指针
return p;
}
void aligned_free(void* p)
{
//计算原内存块的首地址
void* q = ((void **)p)[-1];
free(q);
}