如何检查指针是否指向正确对齐的内存位置?

时间:2017-02-07 15:14:21

标签: c++ c++11 c++14 memory-alignment c++17

给定void *某个存储,如何在没有任何实现定义的行为的情况下检查它是否指向正确对齐的存储?

当然我们有std::align,但有更有效的方法吗?

template <std::size_t alignment>
inline bool is_aligned(void * ptr) noexcept {
    std::size_t max = 1u;
    return std::align(alignment, 1u, ptr, max);
}

PS:我需要以兼容C ++标准的方式执行此操作,而不依赖于任何特定于平台的(实现定义的)黑客攻击。

PPS:我为我(理解)英语而道歉,而不是我的母语。

EDIT(2018.08.24):从标题中删除了“有效”,添加了更多措辞,强调我不希望任何实现定义或特定于平台的行为。

1 个答案:

答案 0 :(得分:20)

如果在使用所需的对齐方式划分地址时余数不为零,则地址不对齐。

inline bool
is_aligned(const void * ptr, std::uintptr_t alignment) noexcept {
    auto iptr = reinterpret_cast<std::uintptr_t>(ptr);
    return !(iptr % alignment);
}
但是,由于演员阵容,这不可能是constexpr。

此外,这依赖于实现定义的事实,即从指针到整数的转换必须保留地址的数字表示。正如评论所指出的那样,标准无法保证,因此该功能不一定能够移植到所有平台。这也是事实,因为实现提供std::uintptr_t是可选的。

我希望在对齐类型时才需要这样做,所以这可能更方便:

template<class T>
bool
is_aligned(const void * ptr) noexcept {
    auto iptr = reinterpret_cast<std::uintptr_t>(ptr);
    return !(iptr % alignof(T));
}