Home > Blockchain >  How does one align a pointer that is allocated on the heap (using malloc)?
How does one align a pointer that is allocated on the heap (using malloc)?

Time:11-16

This causes a seg fault when I try to align the pointer returned by calloc to BY2PAGE. Is there a way (or is it even legal) to modify the pointer such that it is aligned after the allocation?

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define BY2PG 0x1000
char * vm;


static int roundup(u_int n, int align) {
    if(n % align == 0) ; 
    // is already aligned so
    // no action required, else
    // align it:
    else n  = (align - (n % align));
    
    return n;
}

int main() {

    vm = (char *) calloc(0x100000, sizeof(char));

    vm = (char *) roundup((u_int)vm, BY2PG);

    vm[0] = 5; // seg fault
}

CodePudding user response:

Rather than risk implementation and undefined behavior with brittle user code, to align an allocation, use:

void *aligned_alloc(size_t alignment, size_t size);

The aligned_alloc function allocates space for an object whose alignment is specified by alignment, whose size is specified by size, ...


OP is assuming 1) (u_int)vm does not lose vital information (I think this is the seg fault source) 2) that the adjusted integer, cast to an int, converted back to a pointer is valid 3) calloc(large_value, 1) returned non-NULL @Lindydancer .

Even the initial allocation is suspect as calloc(0x100000, sizeof(char)); it is unclear how many 0x1000 sized blocks are available to use after the questionable roundup().

CodePudding user response:

Thanks to @WeatherVane - this version works as I expected

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define BY2PG 0x1000
char * vm;


static uintptr_t roundup(uintptr_t n, int align) {
    if(n % align == 0) ; 
    // is already aligned so
    // no action required, else
    // align it:
    else n  = (align - (n % align));
    
    return n;
}

int main() {

    vm = (char *) calloc(0x100000, sizeof(char));

    printf("x\n", vm);

    vm = (char *) roundup((uintptr_t)vm, BY2PG);

    printf("x\n", vm);

    vm[0] = 5;

    printf("%d\n", vm[0]);
}
  • Related