C语言中结构体的偏移量与内存对齐

C语言中结构体在内存中的偏移量问题。

查看对齐模数
#pragma pack(show)
默认对齐模数是8。

自定义数据的对齐规则

  • 第一个属性开始 从0开始偏移
  • 第二个属性开始 要放在 该类型的大小 与 对齐模数比 取小的值 的整数倍
  • 所有属性都计算完后,再整体做二次偏移,将整体计算的结果 要放在 结构体最大类型 与对齐模数比 取小的值的 整数倍上

结构体嵌套结构体

  • 结构体嵌套结构体时候,子结构体放在该结构体中最大类型,和对齐模数比的整数倍上即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <stddef.h>

struct Teacher {
char a; //0 ~ 3
int b; //4 ~ 7
};

void test01() {

struct Teacher t1;
struct Teacher *p = &t1;

printf("b的属性偏移量为:%d\n", (int) &(p->b) - (int) p);

printf("b的属性偏移量为:%d\n", offsetof(struct Teacher, b));

}

//通过偏移量 操作内存
void test02() {
struct Teacher t1 = {'a', 10};

printf("t1.b = %d\n", *(int *) ((char *) &t1 + offsetof(struct Teacher, b)));

printf("t1.b = %d\n", *(int *) ((int *) &t1 + 1));

}


struct Teacher2 {
char a;
int b;
struct Teacher c;
};

void test03() {
struct Teacher2 t1 = {'a', 10, 'b', 20};

int offset1 = offsetof(struct Teacher2, c);
int offset2 = offsetof(struct Teacher, b);

printf("%d\n", *(int *) ((char *) &t1 + offset1 + offset2));


printf("%d\n", ((struct Teacher *) ((char *) &t1 + offset1))->b);

}

int main() {
//test01();
//test02();
test03();
return 0;
}