14.1. Выделение выровненной памяти: posix_memalign() и memalign()

We use cookies. Read the Privacy and Cookie Policy

14.1. Выделение выровненной памяти: posix_memalign() и memalign()

Для большинства задач отлично подходят стандартные процедуры выделения памяти — malloc(), realloc() и т.д. Но иногда может понадобиться память, которая выровнена тем или иным способом. Другими словами, адрес первого выделенного байта является кратным какого-нибудь числа. (Например, на некоторых системах копирование памяти осуществляется значительно быстрее, если используются буфера, выровненные по границе слова.) Такую службу предоставляют две функции:

#include <stdlib.h>

int posix_memalign(void **memptr, size_t alignment, size_t size);

 /* POSIX ADV */

void *memalign(size_t boundary, size_t size); /* Обычная */

posix_memalign() является более новой функцией; она является частью другого необязательного расширения, «Консультативной информации» («Advisory Information»). Работа функции отличается от других функций выделения памяти Linux. При наличии проблемы она не возвращает -1. Вместо этого возвращаемое значение равно 0 при успехе или значению errno в случае неудачи. Аргументы следующие:

void **memptr

Указатель на переменную void*. Указываемая переменная будет содержать адрес выделенного блока памяти. Выделенная память освобождается с помощью free().

size_t alignment

Требуемое выравнивание. Оно должно быть кратно sizeof(void*) и быть степенью двойки.

size_t size

Число выделяемых байтов.

memalign() является нестандартной, но широко доступной функцией, которая работает сходным образом. Возвращаемое значение равно NULL в случае неудачи и запрошенному блоку памяти при успехе, причем boundary (степень двойки) обозначает выравнивание, a size — затребованный размер памяти.

Традиционно выделенная memalign() память не могла быть освобождена с помощью free(), поскольку memalign() использовала для выделения памяти malloc() и возвращала указатель на выровненный подходящим образом байт где-то внутри блока. Версия GLIBC не имеет этой проблемы. Из этих двух функций следует использовать posix_memalign(), если она у вас есть.