我正在开发一个内存池实现,我对指针对齐有点困惑......
假设我有一个内存池分发固定大小的内存块,在内存池创建时我是malloc((size)*(块数))。如果分配的是对象并且大小来自sizeof运算符对齐不应该是一个问题,但如果大小不均匀(他/她想要100个字节块,无论出于何种原因),那么当我分割由malloc给出的块时我最终得到了不对齐的指针。我的问题是我应该总是将块对齐到某个边界,如果是,那么?
答案 0 :(得分:3)
在大多数x86实现上,正确对齐至少是有用的(性能方面)(在其他架构中,某种对齐实际上是强制性的)。你可能会问(像calloc那样)一对参数,以字节为单位的项目大小和项目数,而不仅仅是一个(大小以字节为单位,如malloc一样);那么你可以通过内部对齐(通过将块大小向上舍入)到项目大小之上的下一个更高的2的幂(但是切换到高于16的16个字节的倍数,不要永远加倍,就像@derobert建议并解释一样! - )。这样,如果调用者只想要N个字节没有任何对齐和填充,他们总是可以要求每个1字节的N个项目(就像他们使用calloc一样,并且出于同样的原因; - )。
答案 1 :(得分:2)
X86无需对齐即可正常工作,但数据对齐后性能会更好。 type 的对齐方式通常为sizeof( type ),最多为16(字节)。
我写这个愚蠢的测试程序只是为了确定(假设malloc知道它在做什么),并在我的amd64框中返回16。在32位模式下编译时返回8:
#include <stdlib.h>
#include <stdio.h>
int main() {
int i;
unsigned long used_bits = 0, alignment;
for (i = 0; i < 1000; ++i) {
used_bits |= (unsigned long)malloc(1); /* common sizes */
used_bits |= (unsigned long)malloc(2);
used_bits |= (unsigned long)malloc(4);
used_bits |= (unsigned long)malloc(8);
used_bits |= (unsigned long)malloc(16);
used_bits |= (unsigned long)malloc(437); /* random number */
}
alignment = 1;
while (!(used_bits & alignment)) {
alignment <<= 1;
}
printf("Alignment is: %lu\n", alignment);
return 0;
}