explicación a la implementación alineada de malloc

Esto no es tarea, es puramente para mi propia educación personal.

No pude descubrir cómo implementar un malloc alineado, así que busqué en línea y encontréeste sitio web. Para facilitar la lectura, publicaré el siguiente código:

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

void* aligned_malloc(size_t required_bytes, size_t alignment)
{
    void* p1; // original block
    void** p2; // aligned block
    int offset = alignment - 1 + sizeof(void*);
    if ((p1 = (void*)malloc(required_bytes + offset)) == NULL)
    {
       return NULL;
    }
    p2 = (void**)(((size_t)(p1) + offset) & ~(alignment - 1));
    p2[-1] = p1;
    return p2;
}

void aligned_free(void *p)
{
    free(((void**)p)[-1]);
}

void main (int argc, char *argv[])
{
    char **endptr;
    int *p = aligned_malloc (100, strtol(argv[1], endptr, 10));

    printf ("%s: %p\n", argv[1], p);
    aligned_free (p);
}

La implementación funciona, pero honestamente no puedo entender cómo funciona.

Esto es lo que no puedo entender:

¿Por qué necesitamos un desplazamiento?¿Qué significa anding with~(alignment - 1) realizarp2 Es un doble puntero. ¿Cómo es que podemos devolverlo desde una función que se supone que devuelve un solo puntero?¿Cuál es el enfoque general para resolver este problema?

Cualquier ayuda es muy apreciada.

EDITAR

Esto no es un duplicado de¿Cómo asignar memoria alineada solo usando la biblioteca estándar? porque también necesito saber cómo liberar memoria alineada.

Respuestas a la pregunta(1)

Su respuesta a la pregunta