user2727804
user2727804

Reputation: 87

How to index obstack allocation

I was trying to index memory allocated by an obstack like an array, but I don't know if I can even do that. It seems to allocate the minimum of 16 bytes, and it is always some multiple of 16 bytes. I might just have a bad understanding of how obstacks work.

For example, this code

    #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;
    }

outputs:

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

which doesn't make sense at all to me. Why would everything be offset? If I change the allocation size, it rounds up to the next multiple of 16, i.e. allocating 30 bytes actually allocates 32 bytes.

Upvotes: 2

Views: 398

Answers (1)

jforberg
jforberg

Reputation: 6762

Why would everything be offset?

The computer has rules for where in memory data is allowed to go, this is called alignment. Alignment is different for different types and is specified in the system ABI. On my machine (AMD64 Linux) the alignment is always the same as the type size, e.g. int is a 4-byte type so it has 4-byte alignment. This means that int data should always begin on an address which is a multiple of 4. So 0x0004, 0x000C, 0x0010 would be valid int* values but not 0x0006.

I would guess that 16 bytes is simply the largest alignment of any type on your machine. Since the obstack type doesn't know what data you will put on it, it has to reserve space for the worst case of 16-byte types. This is also the case with malloc() and related functions, which are required to return memory which is suitably aligned for any built-in type.

And because obstack almost certainly uses malloc to allocate memory, its memory will be aligned this way also.

For more info, see the spec on the AMD64 SysV ABI (or the equivalent docs if this is not your system).

Upvotes: 1

Related Questions