自从我发现我的 sizeof() 运算符没有返回我期望的结果以来,我一直在学习结构数据填充。根据我观察到的模式,它将结构成员与最大的数据类型对齐。那么例如...
struct MyStruct1
{
char a; // 1 byte
char b; // 1 byte
char c; // 1 byte
char d; // 1 byte
char e; // 1 byte
// Total 5 Bytes
//Total size of struct = 5 (no padding)
};
struct MyStruct2
{
char a; // 1 byte
char b; // 1 byte
char c; // 1 byte
char d; // 1 byte
char e; // 1 byte
short f; // 2 bytes
// Total 7 Bytes
//Total size of struct = 8 (1 byte of padding between char e and short f
};
struct MyStruct3
{
char a; // 1 byte
char b; // 1 byte
char c; // 1 byte
char d; // 1 byte
char e; // 1 byte
int f; // 4 bytes
// Total 9 bytes
//Total size of struct = 12 (3 bytes of padding between char e and int f
};
但是,如果将最后一个成员设置为 8 字节数据类型,例如 long long,它仍然只添加 3 字节填充,形成四字节对齐结构。但是,如果我以 64 位模式构建,它实际上会对齐 8 个字节(最大的数据类型)。我的第一个问题是,我说它将成员与最大的数据类型对齐是错误的吗?此声明对于 64 位构建来说似乎是正确的,但在 32 位构建中仅适用于最多 4 字节数据类型。这与 CPU 的本机“字”大小有关吗?还是程序本身?
我的第二个问题是,以下内容是否完全浪费空间和糟糕的编程?
struct MyBadStruct
{
char a; // 1 byte
unsigned int b; // 4 bytes
UINT8 c; // 1 byte
long d; // 4 bytes
UCHAR e; // 1 byte
char* f; // 4 bytes
char g; // 1 byte
// Total of 16 bytes
//Total size of struct = 28 bytes (12 bytes of padding, wasted)
};
如何填充不是标准的一部分。因此可以在不同的系统和编译器上以不同的方式完成。通常这样做是为了使变量按其大小对齐,即 size=1 -> 无对齐、size=2 -> 2 字节对齐、size=4 -> 4 字节对齐等等。对于 size=8,通常是 4 或 8 字节对齐。结构本身通常是 4 或 8 字节对齐的。但是 - 只是重复一下 - 它取决于系统/编译器。
在你的情况下,它似乎遵循上面的模式。
So
char a;
int b;
将为 4 字节对齐 int 提供 3 字节填充。
and
char a1;
int b1;
char a2;
int b2;
char a3;
int b3;
char a4;
int b4;
最终将成为 32 字节(再次以 4 字节对齐 int)。
But
int b1;
int b2;
int b3;
int b4;
char a1;
char a2;
char a3;
char a4;
由于 int 已经对齐,因此将仅为 20。
因此,如果内存很重要,请将最大的成员放在第一位。
但是,如果内存并不重要(例如,因为结构体使用得不多),那么最好将事物保持逻辑顺序,以便代码易于人类阅读。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)