对齐的malloc C ++实现

时间:2018-08-20 18:50:29

标签: c++ memory malloc heap

我找到了这段代码:

void* aligned_malloc(size_t required_bytes, size_t alignment) {
int offset = alignment - 1;
void* P = (void * ) malloc(required_bytes + offset);
void* q = (void * ) (((size_t)(p) + offset) & ~(alignment - 1));
return q;
}

这是C ++中对齐的malloc的实现。对齐的malloc是一个支持分配内存的函数,这样 返回的内存地址可被2的特定乘方整除。 示例:

align_malloc(1000,128)将返回一个内存地址,该地址是128的倍数,并且指向大小为1000字节的内存。

但是我不明白第4行。为什么将偏移量加倍?

谢谢

1 个答案:

答案 0 :(得分:1)

  

为什么总和为偏移量的两倍?

offset未被精确地相加两次。偏移量的首次使用是为了分配大小:

void* p = (void * ) malloc(required_bytes + offset);

第二次是对齐:

void* q = (void * ) (((size_t)(p) + offset) & ~(alignment - 1));

说明: ~(alignment - 1)offset求反(请记住int offset = alignment - 1;),它为您提供遮罩,您需要满足所要求的对齐方式。以算术方式,将偏移量相加并对其取反按位和&),将为您提供对齐指针的地址。

该算术如何工作?首先,请记住,malloc()的内部调用是required_bytes + offset个字节。在这种情况下,不是您要求的对齐方式。例如,您想分配10个字节,对齐方式为16(因此所需的行为是分配一个10字节,该地址从一个可被16整除的地址开始)。因此,上面的malloc()将为您提供10+16-1 = 25个字节。就可以被16整除而言,不一定从正确的地址开始。但是,此16-10x000F,其否定(~)为0xFFF0。现在我们按如下方式应用 bitwise和p + 15 & 0xFFF0,这将导致每个指针p都是16的倍数。

但是,等等,为什么要首先添加alignment - 1的偏移量呢?之所以这样做,是因为一旦获得p返回的指针malloc()您无法做的一件事(为了找到最接近的地址,该地址是所请求的对齐方式的倍数),请在之前 p查找,因为这可能会跨入p之前分配的地址空间。为此,首先要添加 alignment - 1,考虑到这一点,它恰好是必须前进的最大值以实现对齐。

*感谢用户DevSolar的一些附加措辞。

注意1:要使这种方式起作用,对齐方式必须是2的幂。此代码段不会强制执行此类操作,因此可能导致意外行为。

注2:一个有趣的问题是如何使用此函数的返回值来实现这种分配的free()版本。