std::align
Определено в заголовке <memory> |
||
|---|---|---|
void* align( std::size_t alignment,
std::size_t size,
void*& ptr,
std::size_t& space );
|
(с 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 << "allocated a.data at " << (void*)a.data
<< " (" << sizeof a.data << " bytes)\n";
// allocate a char
if (char* p = a.aligned_alloc<char>())
{
*p = 'a';
std::cout << "allocated a char at " << (void*)p << '\n';
}
// allocate an int
if (int* p = a.aligned_alloc<int>())
{
*p = 1;
std::cout << "allocated an int at " << (void*)p << '\n';
}
// allocate an int, aligned at 32-byte boundary
if (int* p = a.aligned_alloc<int>(32))
{
*p = 2;
std::cout << "allocated an int at " << (void*)p << " (32 byte alignment)\n";
}
}Возможный вывод:
allocated a.data at 0x7ffd0b331f80 (64 bytes) allocated a char at 0x7ffd0b331f80 allocated an int at 0x7ffd0b331f84 allocated an int at 0x7ffd0b331fa0 (32 byte alignment)
Отчеты об ошибках
Следующие отчеты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение, опубликованное | Корректное поведение |
|---|---|---|---|
| LWG 2377 | C++11 |
alignment должно быть фундаментальным или поддерживаемым расширенным значением выравнивания |
достаточно, чтобы быть степенью двойки |
См. также
alignof оператор(C++11) |
запрашивает требования к выравниванию типа |
alignas спецификатор(C++11) |
указывает, что хранилище для переменной должно быть выровнено на определенное значение |
|
(C++11)(устарело в C++23) |
определяет тип, пригодный для использования в качестве неинициализированного хранилища для типов заданного размера (шаблон класса) |
|
(C++20) |
сообщает компилятору, что указатель выровнен (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/memory/align