std::align
来自cppreference.com
在标头 <memory> 定义 | ||
void* align(std::size_t alignment, std::size_t size, | (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"; // 分配一个 charif(char* p = a.implicit_aligned_alloc<char>()){*p ='a';std::cout<<"char 分配于 "<<(void*)p <<'\n';} // 分配一个 intif(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) | 告知编译器指针已对齐 (函数模板) |