Alignment

From C

Jump to: navigation, search
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

struct align_buffer {
    char *buf;
    size_t size;
    size_t pos;
};

size_t align_(size_t n, size_t align) {
    if (n % align == 0)
        return n;
    
    return n + (align - (n % align));
}

void *align_buf(struct align_buffer *p,
                size_t size,
                size_t align)
{
    size_t padding = align_(p->pos, align);
    p->pos = padding + size;
    return p->buf + padding;
}

void align_free(struct align_buffer *p) {
    free(p->buf);
    free(p);
}

int align_init(struct align_buffer **p, 
               size_t size)
{
    *p = malloc(sizeof **p);
    if (*p == NULL)
        goto error1;
    
    (*p)->buf = malloc(size);
    if ((*p)->buf == NULL)
        goto error2;
    
    (*p)->size = size;
    (*p)->pos = 0;
    
    return 0;
    
    error2:
    free(*p);
    
    error1:
    return -1;
}

#define alignof_(type) offsetof(struct { char c; type m; }, m)

int main(void) {
    struct align_buffer *buf;
    
    if (align_init(&buf, 1024) != 0)
        return -1;
    
    /* ### */
    
    size_t *arr1 = align_buf(buf, 3 * sizeof *arr1, alignof_(size_t));
    
    arr1[0] = 1;
    arr1[1] = 2;
    arr1[2] = 3;
    
    printf("arr1[0]: %zu\n", arr1[0]);
    printf("arr1[1]: %zu\n", arr1[1]);
    printf("arr1[2]: %zu\n", arr1[2]);
    
    uintmax_t *arr2 = align_buf(buf, 3 * sizeof *arr2, alignof_(uintmax_t));
    
    arr2[0] = 123;
    arr2[1] = 123123;
    arr2[2] = 123123123;
    
    printf("arr2[0]: %ju\n", arr2[0]);
    printf("arr2[1]: %ju\n", arr2[1]);
    printf("arr2[2]: %ju\n", arr2[2]);
    
    /* ### */

    align_free(buf);
    
    return 0;
}
Personal tools