对齐与指针中尾随零的数量有何关系?
How is alignment related to the number of trailing zeros in a pointer?
我想了解内存对齐在 C++ 中的工作原理。
如果我没理解错的话,如果n
是一个指针的二进制表示中尾随零的个数,那么这个指针就是对齐到2^n字节的。但是,下面的程序:
#include <bitset>
#include <cstdint>
#include <iostream>
#include <climits>
#include <cassert>
template <typename T>
std::size_t nTrailingZeros(const T* pointer)
{
assert(CHAR_BIT == 8);
std::bitset<8*sizeof(std::uintptr_t)> bits(reinterpret_cast<std::uintptr_t>(pointer));
std::size_t nZeroes{};
while (nZeroes < bits.size() && !bits[nZeroes])
{
++nZeroes;
}
return nZeroes;
}
struct alignas(64) A {int x;};
int main()
{
std::cout << "Alignment: " << alignof (A) << std::endl;
std::cout << "Trailing zeros: " << nTrailingZeros (new A) << std::endl;
}
输出:
Alignment: 64
Trailing zeros: 4
在我的电脑上。
我做错了什么?我希望至少有 6 个尾随零,但我只得到 4 个(建议 16 字节对齐)。
不支持 over-aligned 数据的动态内存分配。不幸的是,您必须自己获取对齐的内存,然后 placement-new 放入其中。
Side-note:您的 bitset
不够大。你想要 8*sizeof (uintptr_t)
位。
我想了解内存对齐在 C++ 中的工作原理。
如果我没理解错的话,如果n
是一个指针的二进制表示中尾随零的个数,那么这个指针就是对齐到2^n字节的。但是,下面的程序:
#include <bitset>
#include <cstdint>
#include <iostream>
#include <climits>
#include <cassert>
template <typename T>
std::size_t nTrailingZeros(const T* pointer)
{
assert(CHAR_BIT == 8);
std::bitset<8*sizeof(std::uintptr_t)> bits(reinterpret_cast<std::uintptr_t>(pointer));
std::size_t nZeroes{};
while (nZeroes < bits.size() && !bits[nZeroes])
{
++nZeroes;
}
return nZeroes;
}
struct alignas(64) A {int x;};
int main()
{
std::cout << "Alignment: " << alignof (A) << std::endl;
std::cout << "Trailing zeros: " << nTrailingZeros (new A) << std::endl;
}
输出:
Alignment: 64 Trailing zeros: 4
在我的电脑上。
我做错了什么?我希望至少有 6 个尾随零,但我只得到 4 个(建议 16 字节对齐)。
不支持 over-aligned 数据的动态内存分配。不幸的是,您必须自己获取对齐的内存,然后 placement-new 放入其中。
Side-note:您的 bitset
不够大。你想要 8*sizeof (uintptr_t)
位。