Je ne pense pas que ce soit possible uniquement avec malloc. Vous pouvez utiliser memalign() :
char *data = memalign(PAGESIZE, alloc_size);
Où PAGESIZE
est la taille d'une page et alloc_size
est la taille de la mémoire qui sera allouée.
La taille de la page peut être trouvée avec sysconf(_SC_PAGESIZE)
.
Il existe des fonctions pour cela que vous êtes censé utiliser.
Si vous ne pouvez pas, pour quelque raison que ce soit, cela se fait généralement en ajoutant la taille du bloc à la taille de l'allocation, puis en utilisant la ruse des nombres entiers pour arrondir le pointeur.
Quelque chose comme ça :
/* 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);
}
Cela n'a pas été testé très profondément mais vous voyez l'idée.
Notez qu'il devient impossible de trouver le bon pointeur vers free()
la mémoire plus tard. Pour résoudre ce problème, nous devrions ajouter des machines supplémentaires :
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;
}
Cela enveloppe un peu la supercherie du pointeur et vous donne un pointeur que vous pouvez free()
, mais vous devez déréférencer dans le aligned
pointeur pour obtenir le pointeur correctement aligné.