如何使用可移植标准C++方法计算前序对齐指针
实现方案
结论
可以实现,无需将指针强转为整数类型,借助C++标准库的std::align即可完成符合可移植要求的实现。
实现原理
std::align是C++11引入的标准库函数,定义于<memory>头文件,专门用于判断给定内存区间是否存在满足指定对齐要求的地址,所有行为都有标准保障,不存在未定义行为。
结合题目给定的前置条件:
- 输入指针
ptr一定属于起始地址对齐到align、长度为align的char数组 - 对齐要求
align一定是2的幂(alignas语法的强制要求)
我们只需要从ptr开始逐字节向低地址遍历,直到找到第一个满足align对齐要求的地址,这个地址就是数组的起始地址。
代码实现
#include <memory> #include <cassert> #include <cstdlib> char* previous_aligned_pointer(char* ptr, size_t align) { while (true) { void* cur_ptr = ptr; size_t available = 1; // 检查当前地址是否满足align对齐,且能放下1字节数据 if (std::align(align, 1, cur_ptr, available) != nullptr) { return ptr; } // 题目保证一定会在遍历到数组首地址时终止,不会越界 --ptr; } } int main() { constexpr int N = 32; alignas(N) char buffer[N]; // 全量边界测试 for (int i = 0; i < N; ++i) { assert(previous_aligned_pointer(&buffer[i], N) == &buffer[0]); } // 原题随机测试 assert(previous_aligned_pointer(&buffer[rand() % N], N) == &buffer[0]); }
补充说明
- 该实现完全符合C++标准要求,所有指针运算都在题目保证的合法内存范围内,不存在未定义行为。
- 没有使用任何指针到整数的强制转换,完全满足题目约束,可在所有支持C++11及以上标准的平台上运行。
- 最坏情况下循环次数等于
align的值,对于常规对齐大小(如16、32、64字节),性能完全可以接受。
内容的提问来源于stack exchange,提问作者VainMan。
相关产品推荐
相关产品推荐

