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字节对齐,为了对齐最大成员填充了很多字节