std::align
来自cppreference.com
<tbody>
</tbody>
| 在标头 <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>
#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 << "a.data 分配于 " << (void*)a.data
<< " (" << sizeof a.data << " 字节)\n";
// 分配一个 char
if (char* p = a.implicit_aligned_alloc<char>())
{
*p = 'a';
std::cout << "char 分配于 " << (void*)p << '\n';
}
// 分配一个 int
if (int* p = a.implicit_aligned_alloc<int>())
{
*p = 1;
std::cout << "int 分配于 " << (void*)p << '\n';
}
// 分配一个 int,对齐于 32 字节边界
if (int* p = a.implicit_aligned_alloc<int>(32))
{
*p = 2;
std::cout << "int 分配于 " << (void*)p << " (32 字节对齐)\n";
}
}
可能的输出:
a.data 分配于 0x7ffc654e8530 (64 字节)
char 分配于 0x7ffc654e8530
int 分配于 0x7ffc654e8534
int 分配于 0x7ffc654e8540 (32 字节对齐)
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 2377 | C++11 | 要求 alignment 为基础或受支持的扩展对齐值
|
仅需要为二的幂 |
参阅
alignof (C++11)
|
查询类型的对齐要求 (operator) |
alignas (C++11)
|
指定该变量的存储应该按指定量对齐 (specifier) |
(C++11 起)(C++23 弃用) |
定义适于用作给定大小的类型的未初始化存储的类型 (类模板) |
(C++20) |
告知编译器指针已对齐 (函数模板) |