объяснение согласованной реализации malloc

Это не домашнее задание, это чисто мое личное образование.

Я не мог понять, как реализовать выровненный malloc, поэтому посмотрел онлайн и нашелэтот сайт, Для удобства чтения я выложу код ниже:

#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);
}

Реализация работает, но я, честно говоря, не могу понять, как она работает.

Вот что я не могу понять:

Почему нам нужно смещение?Что делает с~(alignment - 1) выполнятьp2 это двойной указатель Почему мы можем вернуть его из функции, которая должна возвращать только один указатель?Каков общий подход к решению этой проблемы?

Любая помощь очень ценится.

РЕДАКТИРОВАТЬ

Это не дубликатКак выделить выровненную память только с использованием стандартной библиотеки? потому что мне также нужно знать, как освободить выровненную память.

Ответы на вопрос(3)

Ваш ответ на вопрос