Non credo sia possibile solo con malloc. Puoi usare memalign():
char *data = memalign(PAGESIZE, alloc_size);
Dove PAGESIZE
è la dimensione di una pagina e alloc_size
è la dimensione della memoria che verrà allocata.
La dimensione della pagina può essere trovata con sysconf(_SC_PAGESIZE)
.
Ci sono funzioni per questo che dovresti usare.
Se non puoi, per qualsiasi motivo, il modo in cui ciò viene generalmente fatto è aggiungendo la dimensione del blocco alla dimensione dell'allocazione, quindi usando l'inganno della matematica intera per arrotondare il puntatore.
Qualcosa del genere:
/* Note that alignment must be a power of two. */
void * allocate_aligned(size_t size, size_t alignment)
{
const size_t mask = alignment - 1;
const uintptr_t mem = (uintptr_t) malloc(size + alignment);
return (void *) ((mem + mask) & ~mask);
}
Questo non è stato testato molto a fondo, ma hai avuto l'idea.
Nota che diventa impossibile capire il corretto puntatore a free()
il ricordo dopo. Per risolvere questo problema, dovremmo aggiungere altri macchinari:
typedef struct {
void *aligned;
} AlignedMemory;
AlignedMemory * allocate_aligned2(size_t size, size_t alignment)
{
const size_t mask = alignment - 1;
AlignedMemory *am = malloc(sizeof *am + size + alignment);
am->aligned = (void *) ((((uintptr_t) (am + 1)) + mask) & ~mask);
return am;
}
Questo avvolge un po' l'inganno del puntatore e ti dà un puntatore che puoi free()
, ma devi dereferenziare in aligned
puntatore per ottenere il puntatore correttamente allineato.