如何索引障碍分配

时间:2015-09-14 21:19:04

标签: c memory-management glibc

我试图索引像阵列一样的障碍分配的内存,但我不知道我是否能做到这一点。它似乎分配了最少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个字节。

1 个答案:

答案 0 :(得分:1)

  

为什么一切都会被抵消?

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

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

因为obstack几乎肯定会使用malloc来分配内存,所以它的内存也会以这种方式对齐。

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