如何索引障碍分配

How to index obstack allocation

我试图索引由像数组这样的障碍物分配的内存,但我不知道我是否能做到这一点。它似乎分配了最小的 16 个字节,而且它总是 16 个字节的某个倍数。我可能只是对障碍物的工作原理理解不好。

比如这段代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <obstack.h>

    #define obstack_chunk_alloc malloc
    #define obstack_chunk_free free

    int main(void)
    {
            struct obstack ob_stack;
            obstack_init(&ob_stack);

            double a = 5.0;
            double b = 24.0;
            double c = 2.42;

            double *pa = obstack_copy(&ob_stack, &a, sizeof a);
            double *pb = obstack_copy(&ob_stack, &b, sizeof b);
            double *pc = obstack_copy(&ob_stack, &c, sizeof c);

            printf("%p %p %p\n", pa, pb, pc);
            printf("%f %f %f %f %f %f\n", pa[0], pa[1], pa[2], pa[3], pa[4], pa[5]);

            obstack_free(&ob_stack, NULL);
            return 0;
    }

输出:

    0x683020 0x683030 0x683040
    5.000000 0.000000 24.000000 0.000000 2.420000 0.000000

这对我来说完全没有意义。为什么一切都会被抵消? 如果我更改分配大小,它会四舍五入到下一个 16 的倍数,即分配 30 个字节实际上分配了 32 个字节。

Why would everything be offset?

计算机对允许数据在内存中的位置有规则,这称为对齐。不同类型的对齐方式不同,在系统 ABI 中指定。在我的机器 (AMD64 Linux) 上,对齐总是与字体大小相同,例如int 是 4 字节类型,因此它具有 4 字节对齐。这意味着 int 数据应始终从 4 的倍数的地址开始。因此 0x0004、0x000C、0x0010 将是有效的 int* 值,但不是 0x0006。

我猜想 16 字节只是您机器上任何类型的最大对齐方式。由于 obstack 类型不知道您将在其上放置什么数据,因此它必须为 16 字节类型的最坏情况保留 space。这也是 malloc() 和相关函数的情况,它们是 return 适合任何内置类型对齐的内存所必需的。

而且由于 obstack 几乎肯定会使用 malloc 来分配内存,因此它的内存也会以这种方式对齐。

有关详细信息,请参阅 spec on the AMD64 SysV ABI(如果这不是您的系统,则参阅等效文档)。