找回密码
 立即注册
查看: 151|回复: 19

15F2K60S2单片机,sizeof计算结构体长度和实际对应不上

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-04-29 08:53:52
已绑定手机

8

主题

47

回帖

144

积分

注册会员

积分
144
发表于 2025-4-18 11:07:41 | 显示全部楼层 |阅读模式
STC15F2K60S2单片机,使用Keil编译sizeof计算结构体长度和实际对应不上

整个结构体计算是13字节

但是单独计算和程序运行计算每个变量的长度19个字节

截图202504181103261446.jpg
截图202504181104363325.jpg
回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-4-18 11:13:01 | 显示全部楼层
在嵌入式开发中,结构体的大小计算是一个常见的问题,尤其是在使用C语言进行单片机编程时。您提到的STC15F2K60S2单片机在使用Keil编译时,sizeof计算结构体长度与实际不符的情况,可能涉及以下几个方面的原因:

1. 结构体对齐(Alignment)
C语言编译器在分配结构体成员的内存时,通常会根据成员的数据类型进行对齐。对齐的目的是为了提高内存访问效率,但这也可能导致结构体的实际大小与成员大小的简单累加不一致。

例如,假设您的结构体定义如下:
  1. c
  2. struct MyStruct {
  3.     char a;
  4.     int b;
  5.     short c;
  6.     char d;
  7. };
复制代码
在大多数编译器中,int类型通常需要4字节对齐,short类型需要2字节对齐。因此,编译器可能会在char a之后插入3字节的填充,以确保int b从4字节对齐的地址开始。同样,short c之后可能会插入1字节的填充,以确保char d从下一个字节开始。这样,结构体的实际大小可能会大于成员大小的简单累加。

2. 编译器优化
不同的编译器可能会有不同的优化策略,这些策略可能会影响结构体的大小。Keil编译器可能会根据目标单片机的架构和性能要求,对结构体进行特定的优化,从而导致sizeof的结果与预期不符。

3. 数据类型的大小
在嵌入式系统中,数据类型的大小可能会因编译器和目标平台的不同而有所差异。例如,int在某些平台上可能是2字节,而在其他平台上可能是4字节。因此,如果您在不同的环境中计算结构体大小,结果可能会有所不同。

4. 结构体成员的顺序
结构体成员的顺序也会影响其大小。编译器通常会根据成员的顺序和对齐要求来分配内存。如果成员的顺序不合理,可能会导致更多的填充字节,从而增加结构体的大小。

解决方案
1. 显式对齐:可以使用#pragma pack指令来指定结构体的对齐方式。例如:
  
  1. c
  2.    #pragma pack(push, 1)
  3.    struct MyStruct {
  4.        char a;
  5.        int b;
  6.        short c;
  7.        char d;
  8.    };
  9.    #pragma pack(pop)
复制代码
   这样,编译器会按照1字节对齐来分配结构体成员的内存,从而减少填充字节。

2. 检查数据类型大小:确保您了解目标平台上各数据类型的大小,并在计算结构体大小时考虑这些因素。

3. 使用sizeof验证:在编写代码时,使用sizeof运算符来验证结构体的大小,并根据实际情况调整结构体定义。

示例
假设您的结构体定义如下:
  1. c
  2. struct MyStruct {
  3.     char a;
  4.     int b;
  5.     short c;
  6.     char d;
  7. };
复制代码
在默认对齐方式下,sizeof(struct MyStruct)可能会返回12字节,而不是简单的1 + 4 + 2 + 1 = 8字节。这是因为编译器在char a之后插入了3字节的填充,以确保int b从4字节对齐的地址开始。

通过显式对齐,可以确保结构体的大小与预期一致:
  1. c
  2. pragma pack(push, 1)
  3. struct MyStruct {
  4.     char a;
  5.     int b;
  6.     short c;
  7.     char d;
  8. };
  9. pragma pack(pop)
复制代码
此时,sizeof(struct MyStruct)将返回8字节。

总结
在嵌入式开发中,结构体的大小计算需要考虑对齐、编译器优化、数据类型大小和成员顺序等因素。通过显式对齐和验证,可以确保结构体的大小与预期一致,从而避免潜在的内存访问问题。希望这些信息能帮助您解决在STC15F2K60S2单片机上使用Keil编译时遇到的结构体大小计算问题。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-4-18 11:39:17 | 显示全部楼层
如楼上所述,发一下结构体声明,是否使用了内存对齐。
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-04-29 08:53:52
已绑定手机

8

主题

47

回帖

144

积分

注册会员

积分
144
发表于 2025-4-18 11:41:35 | 显示全部楼层
    size_count = sizeof(eventUsing);
    Uart1_Printf("44:%x\r\n", size_count);//13
    size_count = sizeof(eventUsing.source);
    Uart1_Printf("441:%x\r\n", size_count);//1
    size_count = sizeof(eventUsing.sourceId);
    Uart1_Printf("442:%x\r\n", size_count);//4
    size_count = sizeof(eventUsing.timestamp);
    Uart1_Printf("443:%x\r\n", size_count);//4
    size_count = sizeof(eventUsing.cmdCategory);
    Uart1_Printf("444:%x\r\n", size_count);//1
    size_count = sizeof(eventUsing.cmd1);
    Uart1_Printf("445:%x\r\n", size_count);//1
    size_count = sizeof(eventUsing.cmd2);
    Uart1_Printf("446:%x\r\n", size_count);//1
    size_count = sizeof(eventUsing.msgId);
    Uart1_Printf("447:%x\r\n", size_count);//1
    size_count = sizeof(eventUsing.dataLen);
    Uart1_Printf("448:%x\r\n", size_count);//1
    size_count = sizeof(eventUsing.eventData);
    Uart1_Printf("449:%x\r\n", size_count);//5
    Uart1_Printf("4491:%bu\r\n", eventUsing.eventData[0]);//1
    Uart1_Printf("4492:%bu\r\n", eventUsing.eventData[1]);//2
    Uart1_Printf("4493:%bu\r\n", eventUsing.eventData[2]);//3
    Uart1_Printf("4494:%bu\r\n", eventUsing.eventData[3]);//4
    Uart1_Printf("4495:%bu\r\n", eventUsing.eventData[4]);//5
    Uart1_Printf("offset source: %d\r\n", offsetof(Event_t, source));
    Uart1_Printf("offset sourceId: %d\r\n", offsetof(Event_t, sourceId));
    Uart1_Printf("offset timestamp: %d\r\n", offsetof(Event_t, timestamp));
    Uart1_Printf("offset cmdCategory: %d\r\n", offsetof(Event_t, cmdCategory));
    Uart1_Printf("offset cmd1: %d\r\n", offsetof(Event_t, cmd1));
    Uart1_Printf("offset cmd2: %d\r\n", offsetof(Event_t, cmd2));
    Uart1_Printf("offset msgId: %d\r\n", offsetof(Event_t, msgId));
    Uart1_Printf("offset dataLen: %d\r\n", offsetof(Event_t, dataLen));
    Uart1_Printf("offset eventData: %d\r\n", offsetof(Event_t, eventData));

点评

这个日志eventData,size_count 的类型是一个都看不到哇~  详情 回复 发表于 2025-4-18 11:44
发这个没用,发结构体声明代码,或者上传工程。另外下次回复时点击这里我才能收到提醒~。不然只能F5不停刷新了。 [attachimg]94364[/attachimg]  详情 回复 发表于 2025-4-18 11:43
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-4-18 11:43:53 | 显示全部楼层
王*** 发表于 2025-4-18 11:41
size_count = sizeof(eventUsing);
    Uart1_Printf("44:%x\r\n", size_count);//13
    size_count = ...

发这个没用,发结构体声明代码,或者上传工程。另外下次回复时点击这里我才能收到提醒~。不然只能F5不停刷新了。
截图202504181143239715.jpg
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-4-18 11:44:47 | 显示全部楼层
王*** 发表于 2025-4-18 11:41
size_count = sizeof(eventUsing);
    Uart1_Printf("44:%x\r\n", size_count);//13
    size_count = ...

这个日志eventData,size_count 的类型是一个都看不到哇~
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-04-29 08:53:52
已绑定手机

8

主题

47

回帖

144

积分

注册会员

积分
144
发表于 2025-4-18 11:45:59 | 显示全部楼层
增加数据
截图202504181142007607.jpg
截图202504181142274784.jpg
截图202504181144379076.jpg
截图202504181144413453.jpg
截图202504181144511866.jpg
截图202504181144551653.jpg
截图202504181145418682.jpg
截图202504181145451597.jpg
截图202504181145485477.jpg
截图202504181145529487.jpg
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-04-29 08:53:52
已绑定手机

8

主题

47

回帖

144

积分

注册会员

积分
144
发表于 2025-4-18 11:46:35 | 显示全部楼层
erci*** 发表于 2025-4-18 11:44
这个日志eventData,size_count 的类型是一个都看不到哇~

上传了,您看一下
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-04-29 08:53:52
已绑定手机

8

主题

47

回帖

144

积分

注册会员

积分
144
发表于 2025-4-18 11:47:52 | 显示全部楼层
上传
截图202504181147435550.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-4-18 11:58:37 | 显示全部楼层
是不是漏了这个

截图202504181158192945.jpg
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 19:54 , Processed in 0.147011 second(s), 112 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表