我写了一个非常简单的例子,演示了 3 字节的地址对齐struct
。
#include <iostream>
struct Silly {
char a;
char b;
char c;
};
int main() {
std::cout << "sizeof(Silly): " << sizeof(Silly) << std::endl;
std::cout << "alignof(Silly): " << alignof(Silly) << std::endl;
auto p_silly = new Silly[2];
std::cout << "address[0]: " << &p_silly[0] << std::endl;
std::cout << "address[1]: " << &p_silly[1] << std::endl;
std::cout << "stride: " << &p_silly[1] - &p_silly[0] << std::endl;
delete[] p_silly;
}
用 编译它g++ -std=c++23
,我发现以下结果:
sizeof(Silly): 3
alignof(Silly): 1
address[0]: 0x63b1ada176c0
address[1]: 0x63b1ada176c3
stride: 1
这个输出对我来说没有任何意义。
sizeof() = 3
是合理的,因为结构体包含 3 个字节的数据。没有填充,因为每个字段都是一个char
,处理器可以从任何地址加载和存储单个字节。
alignof() = 1
对我来说没有任何意义。对齐是指可以分配对象的连续地址之间的字节数。我希望在3
这里看到一个值?
这两个地址表明两个地址struct Silly
相邻分配,没有填充。第二个对象的地址比第一个对象的地址长 3 个字节。这是有道理的。
stride
一开始我很困惑,但我意识到这是两个地址之间的元素数。一开始我以为应该是两个地址之间的字节数。
为什么alignof
等于1
?
对齐并不是你所想的那样。它不是两个相同类型的对象可以共存的位置之间的字节数。它是可以分配相同类型的对象的有效地址之间的字节数。
Silly
尝试将两个实例放置在连续对齐的地址处会发生重叠,这并不重要。