2

我正在研究内存池实现,我对指针对齐有点困惑......

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

4

2 回答 2

3

在大多数 x86 实现中,正确的对齐至少是有帮助的(在性能方面)(在其他架构中,某种对齐实际上是强制性的)。您可能会要求(像 calloc 那样)一对参数,以字节为单位的项目大小和项目数,而不仅仅是一个(以字节为单位的大小,像 malloc 那样);然后你可以本质上对齐(通过四舍五入块大小)到项目大小之上的 2 的下一个更高的幂(但切换到 16 以上的 16 个字节的倍数,不要永远加倍,就像@derobert 推荐和解释的那样! -)。这样,如果调用者只想要 N 个字节而不需要任何对齐或填充,他们总是可以请求 N 个每个 1 字节的项目(就像他们使用 calloc 并且出于相同的原因;-)。

于 2009-09-11T04:45:38.313 回答
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;
}
于 2009-09-11T04:29:09.850 回答