В этом сообщении stackoverflow есть комментарий:
new и malloc по умолчанию выравнивают адрес по 8 байтам (x86) или 16 байтам
(x64), что является оптимальным для большинства сложных данных.
Однако в следующем коде выравнивание памяти, выделенной malloc, составило 8 байт.
Код: Выделить всё
struct A {
uint64_t num1;
uint32_t num2;
uint16_t num3;
};
printf("alignof(A) = %d\n", alignof(A));
A* a = (A *) malloc(sizeof(A));
printf("sizeof(A) = %d\n", sizeof (A));
printf("alignof(a) = %d\n", alignof (a));
printf("alignof(*a) = %d\n", alignof (*a));
printf("Address pointed by a = %d\n", (uint64_t) a);
Код: Выделить всё
alignof(A) = 8
sizeof(A) = 16
alignof(a) = 8
alignof(*a) = 8
Address pointed by a = 1082707680
Адрес, выделенный malloc, выровнен по 16 байтам. Я запускал эту программу 10-15 раз и всегда получал адреса, выровненные по 16 байтам. Но оператор alignof возвращает 8 байт.
Цитата из справочной страницы malloc:
malloc(), calloc(), realloc () и функции reallocarray() возвращают
указатель на выделенную память, который соответствующим образом выровнен для любого
типа, который соответствует запрошенному размеру или меньше.
В документации нет упоминаний о 8 или 16 байтах... просто они должны быть соответствующим образом выровнены.
Если я добавлю в структуру 16-байтовую переменную, теперь выравнивание Объем памяти, выделенной malloc, составляет 16 байт, что имеет смысл, поскольку выравнивание агрегатного типа, такого как struct, основано на самом большом типе в структуре. Но в каком-то смысле это не имеет смысла — malloc принимает в качестве параметра только размер. Итак, откуда malloc узнает, что я собираюсь интерпретировать эту память как тип A.
В целом, я просто хочу понять, как распределение памяти работает при распределении кучи.< /p>
Окружающая среда: я использую clang и запускал эту программу на машине Linux Arm64.
Подробнее здесь: https://stackoverflow.com/questions/790 ... ted-values