[在研究Linux操作系统的内存管理时,我看到实现对齐的malloc函数的一般解决方案是以下代码:
void* aligned_malloc(size_t required_bytes, size_t alignment)
{
void* p1; // original block
void** p2; // aligned block
int offset = alignment - 1 + sizeof(void*);
if ((p1 = (void*)malloc(required_bytes + offset)) == NULL)
{
return NULL;
}
p2 = (void**)(((size_t)(p1) + offset) & ~(alignment - 1));
p2[-1] = p1;
return p2;
}
此解决方案的问题是,由于alignment
,仅当& ~(alignment - 1)
为2的幂时,它才能正常工作。此外,alignment
必须是size_t
数据类型,以便适合指针p1
的数据类型。由于这些限制,我想到了另一种解决方案:
void* aligned_malloc(size_t required_bytes, size_t alignment)
{
void* p1; // original block
void** p2; // aligned block
int offset = alignment - 1 + sizeof(void*);
if ((p1 = (void*)malloc(required_bytes + offset)) == NULL)
{
return NULL;
}
offset = (size_t)(p1) % alignment; // offset is used so that I don't have to declare another variable
p2 = (void**)((size_t)(p1) + (alignment - offset));
p2[-1] = p1;
return p2;
}
此解决方案解决了两个问题,即alignment
不必既不是2的幂,也不是size_t
数据类型。我的问题是,为什么不使用这种方式来实现对齐的malloc?使人们选择按位运算符&
和~
代替解决方案的缺点是什么?
非常感谢您的帮助。谢谢。
可能是因为alignment
是一个变量(对于编译器而言)是未知值,这意味着编译器无法通过简单的操作轻松实现它。
按位运算比%
运算符所需的算术(尤其是除法)更简单,更高效。