std:: align
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Определено в заголовочном файле
<memory>
|
||
|
void
*
align
(
std::
size_t
alignment,
std::
size_t
size,
|
(начиная с C++11) | |
Дано указатель ptr на буфер размером space , возвращает указатель, выровненный по заданному alignment для size количества байт и уменьшает аргумент space на количество байт, использованных для выравнивания. Возвращается первый выровненный адрес.
Функция изменяет указатель только в том случае, если в буфере возможно разместить требуемое количество байт, выровненных по заданному alignment. Если буфер слишком мал, функция не выполняет никаких действий и возвращает nullptr .
Поведение не определено, если alignment не является степенью двойки.
Содержание |
Параметры
| alignment | - | требуемое выравнивание |
| size | - | размер выравниваемого хранилища |
| ptr | - |
указатель на непрерывное хранилище (буфер) размером не менее
space
байт
|
| space | - | размер буфера, в котором производится операция |
Возвращаемое значение
Скорректированное значение ptr , или значение нулевого указателя, если предоставленное пространство слишком мало.
Пример
Демонстрирует использование
std::align
для размещения объектов разных типов в памяти.
#include <iostream> #include <memory> #include <new> template<std::size_t N> struct MyAllocator { std::byte data[N]; std::size_t sz{N}; void* p{data}; MyAllocator() = default; // Примечание: корректно определено только для типов с неявным временем жизни template<typename T> T* implicit_aligned_alloc(std::size_t a = alignof(T)) { if (std::align(a, sizeof(T), p, sz)) { T* result = std::launder(reinterpret_cast<T*>(p)); p = static_cast<std::byte*>(p) + sizeof(T); sz -= sizeof(T); return result; } return nullptr; } }; int main() { MyAllocator<64> a; std::cout << "allocated a.data at " << (void*)a.data << " (" << sizeof a.data << " bytes)\n"; // Выделение памяти для char if (char* p = a.implicit_aligned_alloc<char>()) { *p = 'a'; std::cout << "allocated a char at " << (void*)p << '\n'; } // Выделение памяти для int if (int* p = a.implicit_aligned_alloc<int>()) { *p = 1; std::cout << "allocated an int at " << (void*)p << '\n'; } // Выделение памяти для int с выравниванием по 32-байтной границе if (int* p = a.implicit_aligned_alloc<int>(32)) { *p = 2; std::cout << "allocated an int at " << (void*)p << " (32-byte alignment)\n"; } }
Возможный вывод:
allocated a.data at 0x7ffc654e8530 (64 bytes) allocated a char at 0x7ffc654e8530 allocated an int at 0x7ffc654e8534 allocated an int at 0x7ffc654e8540 (32-byte alignment)
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| LWG 2377 | C++11 |
alignment
required to be a fundamental or supported extended alignment value
|
only need to be a power of two |
Смотрите также
alignof
(C++11)
|
запрашивает требования к выравниванию типа
(оператор) |
alignas
(C++11)
|
указывает, что память для переменной должна быть выровнена на определенное значение
(спецификатор) |
|
(since C++11)
(deprecated in C++23)
|
определяет тип, подходящий для использования в качестве неинициализированного хранилища для типов заданного размера
(шаблон класса) |
|
(C++20)
|
информирует компилятор о том, что указатель выровнен
(шаблон функции) |