结构体(Struct)内部成员字节对齐问题

【生活经历分享】华师国培 华师伴学 合同都是坑 消费者付款后无法退款和华师国培签合同需小心,合同中都是保护华师的条款,没有保护消费者的条款。
收到钱,就算你因对培训质量不满意,也不能退款。因合同消费者维权肯定十分艰难。
华师伴学的授课方式是看录制的视频,不是真人现场教学。是否是您和孩子想要的学习方式?
各位打算报名的,交费要谨慎!
其他人在小红书上发的,转:

深圳市华师国培教育科技有限公司,黑心机构,大家擦亮眼睛,别被骗了,消费欺诈,虚假承诺,签合同各种坑,收到钱了不履行承诺不退款,乱扣费,维权艰难! - 小红书

 
【说明:欢迎转载!转载请注明出处,且不能修改文章内容。否则,请勿转载!】
 
一、结构体的成员都是基本数据类型
结构体成员开始地址与数据类型相关,为数据类型长度的整体倍。否则,即使给内存赋值成功,结构体成员变量的值仍然无法改变。

 1 typedef struct Tst_Struct_BASIC_T {
 2  uint8 member;
 3  uint16 member2;
 4 }Tst_Struct_BASIC;
 5 typedef struct Tst_Struct_BASIC2_T {
 6  uint8 member;
 7  uint32 member2;
 8 }Tst_Struct_BASIC2;
 9 typedef struct Tst_Struct_BASIC3_T {
10  uint8 member;
11  float member2;
12 }Tst_Struct_BASIC3;
13 typedef struct Tst_Struct_BASIC4_T {
14  uint8 member;
15  uint8 member2;
16 }Tst_Struct_BASIC4;

 1 // 结构体中不同基本数据类型变量地址
 2 Tst_Struct_BASIC basic_var = { 0 };
 3 Tst_Struct_BASIC2 basic_var2 = { 0 };
 4 Tst_Struct_BASIC3 basic_var3 = { 0 };
 5 Tst_Struct_BASIC4 basic_var4 = { 0 };
 6  
 7 TRACE("size of basic_var: %d\n", sizeof(basic_var)); // size of basic_var: 4
 8 TRACE("size of basic_var2: %d\n", sizeof(basic_var2)); // size of basic_var2: 8
 9 TRACE("size of basic_var3: %d(size of float: %d)\n", sizeof(basic_var3), sizeof(float)); // size of basic_var3: 8(size of float: 4)
10 TRACE("size of basic_var4: %d\n", sizeof(basic_var4)); // size of basic_var4: 2
11  
12 BYTE* tst_point = (BYTE*)&basic_var;
13 uint8 value_8b = 11;
14 uint16 value_16b = 22;
15 memcpy(tst_point, &value_8b, sizeof(value_8b));
16 memcpy(tst_point + 1, &value_16b, sizeof(value_16b));
17 TRACE("value of struct 1: %d %d\n", basic_var.member, basic_var.member2); // value of struct 1: 11 0
18 memcpy(tst_point + 2, &value_16b, sizeof(value_16b));
19 TRACE("value of struct 1: %d %d\n", basic_var.member, basic_var.member2); // value of struct 1: 11 22
20  
21 BYTE* tst_point2b = (BYTE*)&basic_var2;
22 uint16 value_32b = 33;
23 memcpy(tst_point2b, &value_8b, sizeof(value_8b));
24 memcpy(tst_point2b + 1, &value_16b, sizeof(value_16b));
25 TRACE("value of struct 2: %d %d\n", basic_var2.member, basic_var2.member2); // value of struct 2: 11 0
26 memcpy(tst_point2b + 2, &value_16b, sizeof(value_16b));
27 TRACE("value of struct 2: %d %d\n", basic_var2.member, basic_var2.member2); // value of struct 2: 11 0
28 memcpy(tst_point2b + 4, &value_32b, sizeof(value_32b));
29 TRACE("value of struct 2: %d %d\n", basic_var2.member, basic_var2.member2); // value of struct 2: 11 33
 结构体内存示例:

图片

  通过 Debug 查看内存与结构体变量的值进行对比:

图片

  

二、结构体的成员是结构体
子结构体开始地址与子结构体成员类型有关,开始地址为最长类型的整体倍。

typedef struct Tst_Struct_UINT8_T {
 uint8 member;
 uint8 member2;
 uint8 member3;
 uint8 member4;
 uint8 member5;
 uint8 member6;
 uint8 member7;
 uint8 member8;
}Tst_Struct_UINT8;
typedef struct Tst_Struct_UINT16_T {
 uint16 member;
 uint16 member2;
 uint16 member3;
 uint16 member4;
}Tst_Struct_UINT16;
typedef struct Tst_Struct_UINT32_T {
  uint32 member;
 uint32 member2;
}Tst_Struct_UINT32;
typedef struct Tst_Struct_UINT64_T {
 uint64 member;
}Tst_Struct_UINT64;
 
typedef struct Tst_Struct_Size_Addr_T {
 uint8 member;
 Tst_Struct_UINT8 member8;
}Tst_Struct_Size_Addr;
typedef struct Tst_Struct_Size_Addr2_T {
 uint8 member;
 Tst_Struct_UINT16 member16;
}Tst_Struct_Size_Addr2;
typedef struct Tst_Struct_Size_Addr3_T {
 uint8 member;
 Tst_Struct_UINT32 member32;
}Tst_Struct_Size_Addr3;
typedef struct Tst_Struct_Size_Addr4_T {
 uint8 member;
 Tst_Struct_UINT64 member64;
}Tst_Struct_Size_Addr4;
 1 // 结构体嵌套时子结构体变量开始地址测试
 2 Tst_Struct_Size_Addr tst_addr_1 = { 0 };
 3 Tst_Struct_Size_Addr2 tst_addr_2 = { 0 };
 4 Tst_Struct_Size_Addr3 tst_addr_3 = { 0 };
 5 Tst_Struct_Size_Addr4 tst_addr_4 = { 0 };
 6  
 7 TRACE("sizeof tst_addr_1: %d\n", sizeof(tst_addr_1)); // sizeof tst_addr_1: 9
 8 TRACE("sizeof tst_addr_2: %d\n", sizeof(tst_addr_2)); // sizeof tst_addr_1: 10
 9 TRACE("sizeof tst_addr_3: %d\n", sizeof(tst_addr_3)); // sizeof tst_addr_1: 12
10 TRACE("sizeof tst_addr_4: %d\n", sizeof(tst_addr_4)); // sizeof tst_addr_1: 16
11  
12 // 子结构体变量首地址,与结构体首地址之差
13 size_t offset1 = (unsigned long long)(&(tst_addr_1.member8)) - (unsigned long long)(&tst_addr_1);
14 size_t offset2 = (unsigned long long)(&(tst_addr_2.member16)) - (unsigned long long)(&tst_addr_2);
15 size_t offset3 = (unsigned long long)(&(tst_addr_3.member32)) - (unsigned long long)(&tst_addr_3);
16 size_t offset4 = (unsigned long long)(&(tst_addr_4.member64)) - (unsigned long long)(&tst_addr_4);
17 TRACE("Addr 08: 0x%x 0x%x %d\n", &tst_addr_1, &(tst_addr_1.member8), offset1); // Addr 08: 0x69cfa258 0x69cfa259 1
18 TRACE("Addr 16: 0x%x 0x%x %d\n", &tst_addr_2, &(tst_addr_2.member16), offset2); // Addr 16: 0x69cfa288 0x69cfa28a 2
19 TRACE("Addr 32: 0x%x 0x%x %d\n", &tst_addr_3, &(tst_addr_3.member32), offset3); // Addr 32: 0x69cfa2b8 0x69cfa2bc 4
20 TRACE("Addr 64: 0x%x 0x%x %d\n", &tst_addr_4, &(tst_addr_4.member64), offset4); // Addr 64: 0x69cfa2e8 0x69cfa2f0 8
21 uint8* tst_point1 = (uint8*)&tst_addr_1;
22 uint8* tst_point2 = (uint8*)&tst_addr_2;
23 uint8* tst_point3 = (uint8*)&tst_addr_3;
24 uint8* tst_point4 = (uint8*)&tst_addr_4;
25  
26 // 指向 Tst_Struct_UINT8_T -> uint8 member;
27 uint8 value_08 = 8;
28 uint16 value_16 = 16;
29 uint32 value_32 = 32;
30 uint64 value_64 = 64;
31 memcpy((tst_point1 + 1), &value_08, sizeof(value_08));
32 if ((uint8)(tst_point1 + 1) == value_08) {
33  TRACE("same to value_08\n");
34 }
35 memcpy((tst_point2 + 1), &value_16, sizeof(value_16));
36 if ((uint8)(tst_point2 + 1) == value_16) {
37  TRACE("same to value_16 1 - %d <> %d\n", value_16, tst_addr_2.member16.member); // same to value_16 1 - 16 <> 0
38 }
39 memcpy((tst_point2 + 2), &value_16, sizeof(value_16));
40 if ((uint8)(tst_point2 + 2) == value_16) {
41  TRACE("same to value_16 2 - %d <> %d\n", value_16, tst_addr_2.member16.member); // same to value_16 2 - 16 <> 16
42 }
43 memcpy((tst_point3 + 1), &value_32, sizeof(value_32));
44 if ((uint8)(tst_point3 + 1) == value_32) {
45  TRACE("same to value_32 1 - %d <> %d\n", value_32, tst_addr_3.member32.member); // same to value_32 1 - 32 <> 0
46 }
47 memcpy((tst_point3 + 2), &value_32, sizeof(value_32));
48 if ((uint8)(tst_point3 + 2) == value_32) {
49  TRACE("same to value_32 2 - %d <> %d\n", value_32, tst_addr_3.member32.member); // same to value_32 2 - 32 <> 0
50 }
51 memcpy((tst_point3 + 4), &value_32, sizeof(value_32));
52 if ((uint8)(tst_point3 + 4) == value_32) {
53  TRACE("same to value_32 3 - %d <> %d\n", value_32, tst_addr_3.member32.member); // same to value_32 3 - 32 <> 32
54 }
55 memcpy((tst_point4 + 1), &value_64, sizeof(value_64));
56 if ((uint8)(tst_point4 + 1) == value_64) {
57  TRACE("same to value_64 1 - %d <> %d\n", value_64, tst_addr_4.member64.member); // same to value_64 1 - 64 <> 0
58 }
59 memcpy((tst_point4 + 2), &value_64, sizeof(value_64));
60 if ((uint8)(tst_point4 + 2) == value_64) {
61  TRACE("same to value_64 2 - %d <> %d\n", value_64, tst_addr_4.member64.member); // same to value_64 2 - 64 <> 0
62 }
63 memcpy((tst_point4 + 4), &value_64, sizeof(value_64));
64 if ((uint8)(tst_point4 + 4) == value_64) {
65  TRACE("same to value_64 3 - %d <> %d\n", value_64, tst_addr_4.member64.member); // same to value_64 3 - 64 <> 0
66 }
67 memcpy((tst_point4 + 8), &value_64, sizeof(value_64));
68 if ((uint8)(tst_point4 + 8) == value_64) {
69  TRACE("same to value_64 4 - %d <> %d\n", value_64, tst_addr_4.member64.member); // same to value_64 4 - 64 <> 64
70 }

 

结构体&子结构体内存示例:

图片

 通过 Debug 查看内存与结构体变量的值进行对比:

0
 
测试结构体指针指向内存块,观察结构体的数值,也发现部分中间的内存数值未在结构体中出现。如下图:

图片

 

 
posted @ 2025-11-18 09:41  91program  阅读(10)  评论(0)    收藏  举报