跳转至

C内存对齐

在C语言中,结构体的内存布局受到__对齐__和__填充__的影响。不同数据结构有不同的对齐要求,如int要求4字节、double要求8字节

核心目的:确保后面成员的起始内存是字节对齐的。

1. 举例1

struct MyStruct {
    int a;        // 4 bytes
    double arr[2]; // 16 bytes (2 * 8 bytes)
};

内存布局为:

| int (4 bytes) | padding (4 bytes) | double (8 bytes) | double (8 bytes) |

内存视图为:

88 1e 0d 00   00 00 00 00   30 40 0d 00   00 00 00 00

内存分配为:

[a:88 1e 0d 00]   00 00 00 00   [arr[1]:30 40 0d 00   00 00 00 00]

2. 举例2

struct MyStruct {
  i32 a;
  f64 b;
  i8 c;
  i16 d;
  f32 e;
};

内存视图为:

08 00 00 00   00 00 00 00   28 00 00 00   00 00 00 00
88 1e 66 02   00 00 00 00

内存分配为:

[a:08 00 00 00]   00 00 00 00   [b:28 00 00 00   00 00 00 00]
[c:88] 1e [d:66 02]   [e:00 00 00 00]
  • b为了8字节对齐,和a中间隔了4字节;
  • d为了2字节对齐,和c中间隔了1字节;
  • e的位置正好满足4字节对齐

3. 举例3

typedef struct MyStruct {
  i32 a;
  i8 c;
  i16 d;
  f64 b;
  f32 e;
} MyStruct;

内存视图为:

08 00 00 00   00 00 00 00   28 00 00 00   00 00 00 00
88 1e 1f 00   00 00 00 00

内存分配为:

[a:08 00 00 00]   [c:00] 00 [d:00 00]   [b:28 00 00 00   00 00 00 00]
[e:88 1e 1f 00]   00 00 00 00

!!!结构体的对齐通常是其最大成员的对齐要求,成员里有f64(8字节对齐),所以在e元素后填充了4字节

如:将f64修改为f128,内存视图:

[a:00 00 00 00]   [c:00] 00 [d:00 00]   b9 aa 85 39   fc 7f 00 00
[b:08 00 00 00   00 00 00 00   28 00 00 00   00 00 00 00]
[e:88 1e 6c 02]   00 00 00 00   30 40 6c 02   00 00 00 00

最大成员是16字节对齐,为了对齐最大成员填充了很多字节