Проверка выравнивания памяти

Я хочу проверить выравнивание выделенной памяти или нет. Я использую _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

(По-видимому, существуют исключения для более высоких порядков выравнивания, что является необычным требованием.)