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

C++ 如何检查指针是否指向正确对齐的内存位置?,c++,c++11,c++14,memory-alignment,c++17,C++,C++11,C++14,Memory Alignment,C++17,给定某个存储的void*,如何在没有任何实现定义的行为的情况下检查它是否指向正确对齐的存储 当然有,但有没有更有效的方法 template <std::size_t alignment> inline bool is_aligned(void * ptr) noexcept { std::size_t max = 1u; return std::align(alignment, 1u, ptr, max); } 模板 内联布尔对齐(void*ptr)无异常{ 标准:

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

当然有,但有没有更有效的方法

template <std::size_t alignment>
inline bool is_aligned(void * ptr) noexcept {
    std::size_t max = 1u;
    return std::align(alignment, 1u, ptr, max);
}
模板
内联布尔对齐(void*ptr)无异常{
标准:最大尺寸=1u;
返回标准::校准(校准,1u,ptr,最大值);
}

PS:我需要以C++标准兼容的方式来做这件事,而不依赖于任何平台特定的(实现定义的)HACK.< /P> PPS:我为我对英语的理解道歉,它不是我的母语



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

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

inline bool
is_aligned(const void * ptr, std::uintptr_t alignment) noexcept {
    auto iptr = reinterpret_cast<std::uintptr_t>(ptr);
    return !(iptr % alignment);
}

还请注意,根据定义,对齐是特定于平台的,并且根据@Some建议的重新解释转换返回的数值进行操作,这本质上是未定义或实现定义的行为。最后,如果您使用
new
new[]分配内存
您可以确定内存应该与正在使用的类型对齐。也许您可以通过检查路线来告诉我们您实际上试图解决的问题?你为什么要检查它?@Someprogrammerdude当一个人有一个包含任意原始数据的缓冲区时,这会很有用,需要检查它的一部分是否可以作为某种类型的
T
直接访问,或者是否需要使用
std::memcpy
在作为类型
T
@Someprogrammerdude在C++17之前访问之前/之后,将各自的数据从/复制到缓冲区,这仅适用于标准对齐的类型,对于像
struct OveralignedInt{alignas(1024)inti;}
@jotik即使在满足对齐要求的情况下,也可以将任意原始数据(
char
buffer)作为一些
T
进行访问。您必须首先以placement
new
开始对象的生存期。任何指针都可以转换为大小至少为
uintpttr\t
的无符号整数。但是,结果是实现定义的。您假设使用了一个通用的实现,并且内存模型基本上是扁平的,这在现在很可能,但不能保证。@ArneVogel是的,似乎不能保证它能够严格地移植到模糊的平台上,在这些平台上,转换可能会改变对齐方式。@PhilArmstrong 2的补码不用于无符号数字,它没有相关性:)但是是的,任何一个优秀的优化器都可以进行这种转换。@PhilArmstrong我测试了你的函数,还测试了将constexpr添加到我的模板中。令我惊讶的是,它起作用了。我很困惑,因为我不明白为什么可以在constexpr模板中使用reinterpret_cast,而不能在常规的constexpr函数中使用。您能解释/参考标准吗?@PhilArmstrong:Constexpr函数模板的任何模板参数都不能满足所有
Constexpr
要求。这些模板格式错误,不需要诊断。这就是您和@user207933都遇到的问题。
template<class T>
bool
is_aligned(const void * ptr) noexcept {
    auto iptr = reinterpret_cast<std::uintptr_t>(ptr);
    return !(iptr % alignof(T));
}