0
记得计组考试时候遇到过一道题, 计算结构体所占的内存大小, 当时错了, 但是后来也没明白是为什么而错。 今日转而学习了一波, 渐渐解开了一些疑惑
结构体大小的计算公式
结构体大小 = sizeof(数据成员1) + sizeof(数据成员2) + sizeof(数据成员3) + ...
按照道理来说这个公式是没问题的, 但是问题就在这里
内存对齐
VC++ 6.0 指定的默认对齐值为8
规则1
在为结构体中的数据成员分配内存时, 结构体中当前数据成员类型长度为M, 指定的对齐值为N, 那么实际对齐值为q = min(M, N), 其成员的地址安排在q的倍数上。
比如如下代码:
struct tagTEST{
short sShort;
int nInt;
};
很显然, sShort 本来占 2 个字节, 以 2 对齐, 所以只需地址起始部分是2的倍数, 但是下一个数据成员 nInt 应该占用 4 个字节, 故地址应该是 4 的倍数。 所以 在 sShort 之后需要填充两个字节, 来满足对齐条件。
规则2
其实可以发现, 对齐的目标就是使得结构体的整体大小能够被8整除。
如下代码:
struct {
double dDouble;
int nInt;
short sShort;
};
显然, dDouble 占8个字节, nInt 占4个字节, 所以最后的 sShort 必须占用4个字节, 也就是有两个字节是被填充的, 这样才能满足 结构体的大小能够被 8 整除
规则3
并非设定了默认对齐值, 就能将结构体的对齐值锁定, 如果结构体中的数据成员类型最大值为M, 指定的默认对齐值为N, 那么实际对齐值为 min(M, N)
如下代码:
struct {
char cChar;
int iInt;
short sShort;
}
如果是按照8字节对齐, 由规则1 cChar 应该占用 4个字节, nInt 占用 4个字节, 那么sShort 应该占用 8个字节才对, 因为要满足 结构体的大小被8整除嘛。 但是编译器会发现 结构体中最大的 nInt 占4字节空间, 于是对齐值调整为 4 , 从而 sShort 只需要 4字节就够了, 也就是说 只需要额外占用 2个字节。
自定义默认对齐值
#pragma pack(N)
网友评论