Проверка выравнивания памяти
Я хочу проверить выравнивание выделенной памяти или нет. Я использую _aligned_malloc(size, align);
И он возвращает указатель. Могу ли я проверить это, просто разделив содержимое указателя на 16, например? Если содержимое указателя делится на 16, означает ли это, что память выровнена на 16 байтов?
Ответы
Ответ 1
Указатель "aligned" по определению означает, что числовое значение указателя равномерно делится на N (где N - желаемое выравнивание). Чтобы проверить это, нарисуйте указатель на целое число подходящего размера, возьмите модуль N и проверьте, равен ли результат. В коде:
bool is_aligned(void *p, int N)
{
return (int)p % N == 0;
}
Если вы хотите проверить значение указателя вручную, просто посмотрите на шестнадцатеричное представление указателя и посмотрите, заканчивается ли оно с нужным количеством 0 бит. Значение 16-байтного выровненного указателя всегда будет заканчиваться, например, четырьмя нулевыми битами.
Ответ 2
В современной системе Unix указатель, возвращаемый malloc
, скорее всего, по 16 байт, так как это требуется для таких вещей, как SSE. Чтобы проверить выравнивание мощности 2, вы можете использовать:
((unsigned long)p & (ALIGN - 1)) == 0
Это просто более быстрая версия (p % ALIGN) == 0
. (Если ALIGN
является константой, ваш компилятор, вероятно, автоматически использует более быструю версию выше.)
Ответ 3
Память, возвращаемая malloc, выравнивается для всего (т.е. обычно используется выравнивание, которое работает для всего) *. Это означает, что если у вас проблема с выравниванием, это что-то еще.
http://www.delorie.com/gnu/docs/glibc/libc_31.html
http://msdn.microsoft.com/en-us/library/ms859665.aspx
(По-видимому, существуют исключения для более высоких порядков выравнивания, что является необычным требованием.)