std::align — cppreference.com
Материал из cppreference.com
<tbody> </tbody>
| Определено в заголовочном файле |
||
|
|
(начиная с C++11) | |
Учитывая указатель ptr на буфер размером space, возвращает указатель, выровненный по указанному alignment для числа байтов size, и уменьшает аргумент space по количеству байтов, используемых для выравнивания. Возвращается первый выровненный адрес.
Функция изменяет указатель только в том случае, если можно было бы поместить в буфер требуемое количество байтов, выровненных по заданному выравниванию. Если буфер слишком мал, функция ничего не делает и возвращает nullptr.
Поведение не определено, если alignment не является степенью двойки.
Параметры
| alignment | — | желаемое выравнивание |
| size | — | размер хранилища для выравнивания |
| ptr | — | указатель на непрерывное хранилище (буфер) размером не менее space байт
|
| space | — | размер буфера для операции |
Возвращаемое значение
Скорректированное значение ptr или значение нулевого указателя, если предоставленное пространство слишком мало.
Пример
Демонстрирует использование std::align для размещения в памяти объектов разных типов.
#include <iostream> #include <memory> template<std::size_t N> struct MyAllocator { char data[N]; void* p; std::size_t sz; MyAllocator() : p(data), sz(N) {} template<typename T> T* aligned_alloc(std::size_t a = alignof(T)) { if (std::align(a, sizeof(T), p, sz)) { T* result = reinterpret_cast<T*>(p); p = (char*)p + sizeof(T); sz -= sizeof(T); return result; } return nullptr; } }; int main() { MyAllocator<64> a; std::cout << "распределяет a.data в " << (void*)a.data << " (" << sizeof a.data << " байт)\n"; // распределяет char if (char* p = a.aligned_alloc<char>()) { *p = 'a'; std::cout << "распределяет char в " << (void*)p << '\n'; } // распределяет int if (int* p = a.aligned_alloc<int>()) { *p = 1; std::cout << "распределяет int в " << (void*)p << '\n'; } // распределяет int, выровненный по 32-байтовой границе if (int* p = a.aligned_alloc<int>(32)) { *p = 2; std::cout << "распределяет int в " << (void*)p << " (выравнивание по 32 байтам)\n"; } }
Возможный вывод:
распределяет a.data в 0x7ffd0b331f80 (64 байт) распределяет char в 0x7ffd0b331f80 распределяет int в 0x7ffd0b331f84 распределяет int в 0x7ffd0b331fa0 (выравнивание по 32 байтам)
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 2377 | C++11 | alignment должен быть основным или поддерживаемымрасширенным значением выравнивания |
должен быть только степенью двойки |