关于以下代码的2个问题:
1为什么struct b
的大小是12个字节(输出的第2行)?我可以理解为什么a
是12个字节(在4字节边界上对齐k
),但b
不应该是9个字节而不是12个?
2为什么使用&
运算符来获取char
成员的地址不显示有效地址? (最后两行中间输出)
#include<iostream>
using namespace std;
struct a
{
int i;
char j;
int k;
};
struct b
{
int i;
int k;
char j;
};
int main()
{
a s1;
b s2;
cout<<sizeof(a)<<endl;
cout<<sizeof(b)<<endl;
cout<<sizeof(int)<<endl;
cout<<sizeof(char)<<endl;
cout<<&s1.i<<'\t'<<&s1.j<<'\t'<<&s1.k<<endl;
cout<<&s2.i<<'\t'<<&s2.j<<'\t'<<&s2.k<<endl;
}
输出:
12
12
4
1
0x28ff14 - 0x28ff1c
0x28ff08 4A 0x28ff0c
答案 0 :(得分:3)
如果b
大9字节且你有一个数组
b foo[2];
然后foo[1].i
将不会与四字节边界对齐。
对于char成员,他们的地址是char *
类型,std::ostream
对于那些将它们解释为C样式字符串的operator<<
。如果您想查看他们的地址,static_cast<void*>(&s1.j)
是您的朋友。
答案 1 :(得分:1)
为什么struct b的大小为12字节(输出的第2行)?
它有int
个字段,因此与int
具有相同的对齐要求 - 在您的情况下为四个字节。最后添加了三个填充字节,因此大小是四的倍数,以提供所需的对齐。
这甚至适用于结构的末尾,因此数组的下一个元素已正确对齐。
为什么使用
&
运算符来获取不显示有效地址的char成员的地址?
因为<<
将指向字符类型的指针解释为指向C样式字符串的指针,并打印内存内容直到找到零值。要打印地址,请转换为非字符指针类型:
cout << (void*)&j;