关于指针对齐的问题

时间:2009-09-11 03:57:20

标签: pointers alignment

我正在开发一个内存池实现,我对指针对齐有点困惑......

假设我有一个内存池分发固定大小的内存块,在内存池创建时我是malloc((size)*(块数))。如果分配的是对象并且大小来自sizeof运算符对齐不应该是一个问题,但如果大小不均匀(他/她想要100个字节块,无论出于何种原因),那么当我分割由malloc给出的块时我最终得到了不对齐的指针。我的问题是我应该总是将块对齐到某个边界,如果是,那么?

2 个答案:

答案 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;
}