包含双字段的struct的大小

hqt*_*hqt 4 c struct sizeof

首先,我理解结构中的字节填充.但我仍然有一个小测试包含struct中的双字段,我不知道如何解释这个:

typedef struct {
    char a;
    double b;
}data;

typedef struct{
    char a;
    int b;
}single;

int main(){
    printf("%d\n",sizeof(double));
    printf("%d\n",sizeof(single));
    printf("%d\n",sizeof(data));
}
Run Code Online (Sandbox Code Playgroud)

通过这个测试,答案是:8 816.

为什么这个结果会让我思考?

通过第二次测试,我们可以看到我机器上的单词大小是4个字节.

通过第一次测试,我们可以看到double的大小是8个字节.

所以,在struct data:结果应该是12个字节:char为4个字节,double为8个字节.

但是,我不知道为什么结果是16个字节.(跟我这么奇怪)

请为我解释一下,谢谢:)

Ern*_*ill 8

它是十六个字节,因此如果你有一个datas 数组,这些double值都可以在8字节边界上对齐.在内存中正确对齐数据可以在性能上产生很大的不同.未对齐的数据操作起来可能较慢,而获取和存储的速度较慢.


Eri*_*hil 5

通常用于在结构中布置数据的过程本质上是这样的:

  • 设置偏移 = 0。
  • 对于结构中的每个成员:设 A 为其对齐要求(例如,1、2、4 或 8 个字节,可能更多)。加入偏移,使其A的多重所需的字节数(假定A是二的幂,这是可以做到的Offset += -Offset & A-1,假设两个互补的否定。)指定的电流值的偏移进行补偿该成员的。将成员的大小添加到 Offset。
  • 处理完所有成员后:设A为任何成员的最大对齐要求。添加到 Offset 需要的字节数,使其成为 A 的倍数。 Offset 的这个最终值是结构的大小。

正如 Earnest Friedman-Hill 所说,最后一步在结构的末尾添加了填充,以便在它们的数组中,每个结构都以所需的对齐方式开始。

因此,对于诸如 的结构struct { char c; double d; int32_t i; },在典型的实现中,您有:

  • 将偏移量设置为 0。
  • char 要求对齐为 1,因此 Offset 已经是 1 的倍数(0•1 为 0)。将 c 置于此偏移量 0 处。将 c 的大小 1 添加到 Offset,使其为 1。
  • double 需要 8 对齐,因此将 7 添加到 Offset,使其成为 8。将 d 放在此偏移处,8。将 d 的大小,8,添加到 Offset,使其成为 16。
  • int 需要 4 对齐,因此 Offset 已经是 4 的倍数(4•4 是 16)。将 i 放在这个偏移量 16 处。将 i 的大小 4 添加到偏移量,使其为 20。
  • 最后,需要的最大对齐是 8,所以在 Offset 上加上 4,使其成为 24。这个结构体的大小是 24 个字节。

请注意,以上与机器的任何字长无关。它只使用每个成员的对齐要求。每个类型的对齐要求可以不同,也可以与类型的大小不同,以上仍然有效。

(如果对齐要求不是 2 的幂,则算法会中断。这可以通过使最后一步将偏移量增加为所有对齐的最小公倍数的倍数来解决。)