找回密码
 立即注册
查看: 7129|回复: 99

遇到局部变量被意外修改的问题,发现是编译器给2个局部变量分配了相同的地址?

[复制链接]

4

主题

52

回帖

160

积分

注册会员

积分
160
发表于 2023-12-26 19:06:28 | 显示全部楼层 |阅读模式
本帖最后由 zhangzhonghua 于 2023-12-27 16:33 编辑

遇到局部变量被意外修改的问题,仿真,单步跟踪,发现是编译器给2个具有调用关系的函数的2个局部变量分配了相同的地址,这怎么回事?
简化如下。
func1()
{
  xInfo * p = ...;    // 局部变量,指向某结构xInfo的指针,地址 0x0236
   ...
  func2();
                  // 到这里,发现 地址 0x0236 的内容被修改
}

func2()
{
  uchar sw;   // 局部变量,地址居然也是 0x0236
  sw = 0;      // 这里,就会把func1的局部变量p给意外修改了
}
怎么会这样?!怎么办?

本帖被以下淘专辑推荐:

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:396
  • 最近打卡:2025-05-08 07:41:36

45

主题

381

回帖

1595

积分

金牌会员

静坐常思己过,闲谈莫论人非

积分
1595
发表于 2023-12-26 19:18:56 | 显示全部楼层
加个volatile关键字试试
处事要代人所想,读书需切己用功
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:439
  • 最近打卡:2025-05-09 10:01:19

33

主题

2356

回帖

4886

积分

论坛元老

积分
4886
发表于 2023-12-26 19:21:09 | 显示全部楼层
可以搜索一下OVERLAY 功能 ,,,如果资源足够可以关闭这个功能,,或者有能力修改调用树,
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:439
  • 最近打卡:2025-05-09 10:01:19

33

主题

2356

回帖

4886

积分

论坛元老

积分
4886
发表于 2023-12-26 19:23:06 | 显示全部楼层
还有一件事,,你应该不是这样调用的吧,,你的fun2 利用指针调用的么?
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:396
  • 最近打卡:2025-05-08 07:41:36

45

主题

381

回帖

1595

积分

金牌会员

静坐常思己过,闲谈莫论人非

积分
1595
发表于 2023-12-26 19:26:21 | 显示全部楼层
你可以在func1中的func2之前打印输出下*p的内容,在func2中再打印一下*p的内容,看看修没修改

点评

不用 直接看map文件就行了,,,还有一件事,恭喜你成为高级会员啦,,,可以改头像了的说  发表于 2023-12-26 19:33
处事要代人所想,读书需切己用功
回复 支持 反对

使用道具 举报 送花

2

主题

185

回帖

1048

积分

金牌会员

积分
1048
发表于 2023-12-26 20:15:11 | 显示全部楼层
可以在C251选项里选择产生可重入函数功能
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:526
  • 最近打卡:2025-05-09 08:02:13
已绑定手机

47

主题

1750

回帖

2737

积分

金牌会员

积分
2737
发表于 2023-12-26 21:01:16 | 显示全部楼层
加static啊
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-04-30 08:41:32

105

主题

1215

回帖

1万

积分

荣誉版主

积分
12892
发表于 2023-12-27 00:54:23 | 显示全部楼层
本帖最后由 杨为民 于 2023-12-27 00:56 编辑

(1)这种现象很正常,很正确,这是C51编译器优化变量存储。

(2)func2()是func1()的最后一行, 指针P再也不会被使用,覆盖它修改它没有关系。
(3)出现这种现象不用理它。C51是智能优化,如果你在func2()调用后又引用了P,C51自然又会为它们分配不同的地址,不会出错的。
(4)关闭C51优化就不会产生这种现象了。

点评

能否有时间的话开一个贴子,讲讲这个OVERLAY功能吧,,还有调用树的知识。新人不注意这些很容易掉坑的  发表于 2023-12-27 10:09
杨老师,我看您在研究操作系统,想必对于本帖的知识应该有个系统的了解。  发表于 2023-12-27 10:08
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:439
  • 最近打卡:2025-05-09 10:01:19

33

主题

2356

回帖

4886

积分

论坛元老

积分
4886
发表于 2023-12-27 09:06:18 | 显示全部楼层
杨*** 发表于 2023-12-27 00:54
(1)这种现象很正常,很正确,这是C51编译器优化变量存储。

(2)func2()是func1()的最后一行, 指针P再 ...

关于第3点,,就算p不再被调用 也应该分配不同地址,,,就像我说的,他的func2绝对不是这样正常的调用,,,

点评

4)关闭C51优化就不会产生这种现象了。 如果你没有进行其他设置(比如你强制它们Overlay),如果关闭优化还有这种不同层次的变量的地址相同现象,恭喜你中奖了,可以直接向Keil举报  详情 回复 发表于 2023-12-27 19:23
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

4

主题

52

回帖

160

积分

注册会员

积分
160
发表于 2023-12-27 09:49:50 | 显示全部楼层
本帖最后由 zhangzhonghua 于 2023-12-27 09:54 编辑
_奶*** 发表于 2023-12-27 09:06
关于第3点,,就算p不再被调用 也应该分配不同地址,,,就像我说的,他的func2绝对不是这样正常的调用, ...


高手,确实不是函数名调用,而是用函数指针调用。

*g_pFunc = func2;   // 函数指针指向func2()

func1()
{
  xInfo * pStruc = ...;    // 局部变量,指向某结构xInfo的指针,地址 0x0236
   ...
  g_pFunc();   // 相当于调用func2()
                  // 到这里,发现 地址 0x0236 的内容被修改
  ...
}

func2()
{
  uchar sw;   // 局部变量,地址居然也是 0x0236
  sw = 0;      // 这里,就会把func1的局部变量pStruc给意外修改了
}


但是,我的程序里面是要用函数指针的。怎么办?我看看Overlay怎么搞。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-9 13:53 , Processed in 0.139798 second(s), 120 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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