结构体对齐?

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)

数组来了如何处理?

你可能感兴趣的:(结构体对齐?)