搜索
bottom↓
回复: 29

这个指针怎么会出错?

[复制链接]

出0入22汤圆

发表于 2017-1-14 11:04:43 | 显示全部楼层 |阅读模式
本帖最后由 zxq6 于 2017-1-14 15:40 编辑

如题,
函数调用如下:
calc("9-(3*2)");

函数实现的部分代码如下:

  1. double calc(char *expr) {
  2.    
  3.     char c,*rexp,*pp,*pf;
  4.         pp=pf=expr;
  5.         do {
  6.             c = *pp++;
  7.             if (c!=' '&& c!=Tab)
  8.                 *pf++ = c;
  9.         } while (c!='\0');
  10.     }
复制代码


其中用到的变量定义如下:

char c,*rexp,*pp,*pf;

现在发现,do循环第一圈没有问题,第二圈,到
c = *pp++;
的时候,就出现hard fault里面去了。
百思不得其解,请有经验的大虾指导指导,谢谢!

PS:该代码在vc2012上能够很好的运行。出问题的系统为MDK,运行单片机为STM32


经过15楼的指导,最终解决了这个问题。
当然,其他楼层的指导也很有意义,不过,恕我愚钝,当时没能看懂。

反过头看了看,4楼说的才是第一个指出问题真相的,在此一并感谢。
其他的没有提到的楼层,同样感谢,并非忽略。

同时,也感谢26楼的批评,虚心接受哈。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2017-1-14 11:32:07 | 显示全部楼层
你给出的函数调用和函数定义不一致。

出0入22汤圆

 楼主| 发表于 2017-1-14 11:37:21 | 显示全部楼层
lcofjp 发表于 2017-1-14 11:32
你给出的函数调用和函数定义不一致。

谢谢提醒,改了一下。现在这里应该没有问题了。

出0入0汤圆

发表于 2017-1-14 11:45:15 | 显示全部楼层
*pf++ = c;
这句有问题,pf指向的地址是只读的,你可以把参数改成可读写的数组传进来试试。

出0入22汤圆

 楼主| 发表于 2017-1-14 11:52:21 | 显示全部楼层
lcofjp 发表于 2017-1-14 11:45
*pf++ = c;
这句有问题,pf指向的地址是只读的,你可以把参数改成可读写的数组传进来试试。 ...

尝试过。不过目前的问题点没在这里。楼主位描述的,当运行第二圈,上面那个指针++的时候,已经就出错了。
也尝试把出错的地方按照您说的修改过,还是会出错。

出0入0汤圆

发表于 2017-1-14 12:07:25 | 显示全部楼层
zxq6 发表于 2017-1-14 11:52
尝试过。不过目前的问题点没在这里。楼主位描述的,当运行第二圈,上面那个指针++的时候,已经就出错了。 ...

那我觉得找出问题就完全需要调试分析了,用肉眼看代码我是看不出什么问题了。
打开汇编和变量观察,看看具体是什么操作导致的问题,看地址、变量是否异常等。

出0入22汤圆

 楼主| 发表于 2017-1-14 12:24:38 来自手机 | 显示全部楼层
lcofjp 发表于 2017-1-14 12:07
那我觉得找出问题就完全需要调试分析了,用肉眼看代码我是看不出什么问题了。
打开汇编和变量观察,看看 ...

我初步调试了一下,发现指针赋值那个语句没有生效,正常情况下,赋值后,几个指针值应该相等。
当我加了volatile修饰后,前面的问题没了,改在while那里出错了。第一圈就出错,真神奇。

出0入0汤圆

发表于 2017-1-14 13:16:44 | 显示全部楼层
zxq6 发表于 2017-1-14 12:24
我初步调试了一下,发现指针赋值那个语句没有生效,正常情况下,赋值后,几个指针值应该相等。
当我加了v ...

代码开优化了?如果开了就关了试试

出0入22汤圆

 楼主| 发表于 2017-1-14 13:22:34 来自手机 | 显示全部楼层
lcofjp 发表于 2017-1-14 13:16
代码开优化了?如果开了就关了试试

default和0都尝试过。1-3没尝试。一样的结果

出0入8汤圆

发表于 2017-1-14 13:42:52 | 显示全部楼层
zxq6 发表于 2017-1-14 13:22
default和0都尝试过。1-3没尝试。一样的结果

你把对应的汇编代码贴出来看看。

出0入0汤圆

发表于 2017-1-14 13:50:24 | 显示全部楼层
看看expr的地址是多少

出0入22汤圆

 楼主| 发表于 2017-1-14 13:51:16 | 显示全部楼层
security 发表于 2017-1-14 13:42
你把对应的汇编代码贴出来看看。

图中的代码是最新修改测试过的。
代码里面的问题是,执行if(c=='\0')的时候会进入hard fault里面

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入8汤圆

发表于 2017-1-14 13:54:02 | 显示全部楼层
本帖最后由 security 于 2017-1-14 14:15 编辑
zxq6 发表于 2017-1-14 13:51
图中的代码是最新修改测试过的。
代码里面的问题是,执行if(c=='\0')的时候会进入hard fault里面


都没看到有这语句 f(c=='\0')?
我说的是汇编代码,你这边是 C 源码。
(忽略这边的回复吧,回帖时,图片还没更新出来)

出0入0汤圆

发表于 2017-1-14 14:02:29 | 显示全部楼层
本帖最后由 Tliang 于 2017-1-14 14:12 编辑
zxq6 发表于 2017-1-14 13:51
图中的代码是最新修改测试过的。
代码里面的问题是,执行if(c=='\0')的时候会进入hard fault里面


搞错

出0入0汤圆

发表于 2017-1-14 14:05:26 | 显示全部楼层
calc("9-(3*2)");

"9-(3*2)" 的类型是const char*

出0入8汤圆

发表于 2017-1-14 14:18:19 | 显示全部楼层

建议你保留之前的一些信息
不然一个搞错字样,没人知道是谁搞错了

出0入22汤圆

 楼主| 发表于 2017-1-14 14:20:23 | 显示全部楼层
eye 发表于 2017-1-14 14:05
calc("9-(3*2)");

"9-(3*2)" 的类型是const char*

真是这个问题,谢谢~

出0入8汤圆

发表于 2017-1-14 14:21:19 | 显示全部楼层
zxq6 发表于 2017-1-14 14:20
真是这个问题,谢谢~

晕,你上面不是说过改成可修改的数组试验过了,现象依旧吗?

出0入8汤圆

发表于 2017-1-14 14:21:29 | 显示全部楼层
本帖最后由 lw2012 于 2017-1-14 14:25 编辑

为什么这个问题会引起hard fault ?

出0入22汤圆

 楼主| 发表于 2017-1-14 14:25:46 | 显示全部楼层
security 发表于 2017-1-14 14:21
晕,你上面不是说过改成可修改的数组试验过了,现象依旧吗?

是的,尝试把这个语句
c = *pp++;
修改为
c=pp[idx];
idx++;

这样,也会进入hard fault

出0入22汤圆

 楼主| 发表于 2017-1-14 14:27:31 | 显示全部楼层
lw2012 发表于 2017-1-14 14:21
1 楼主先要确定的确是因为这个函数调用引起的hardfault。
2 看楼主的mdk版本较低,建议换新版本试试。关掉 ...

谢谢提醒。我的mdk版本是4.73,应为没有升级的理由,所以一直沿用着。看来跟编译环境也有很大关系?
不过,我尝试在软件下仿真,结果也是不会出错,但是一下载到单片机里面,就会有问题。

出0入8汤圆

发表于 2017-1-14 14:30:53 | 显示全部楼层
本帖最后由 security 于 2017-1-14 14:47 编辑
zxq6 发表于 2017-1-14 14:25
是的,尝试把这个语句
c = *pp++;
修改为


你没理解上面 lcofjp 坛友的意思。
lcofjp 坛友的意思,跟 15 楼 eye 坛友的意思是一样的。
进而误导了下面的坛友。

编辑增加:
另外,刚好 15 楼 eye 坛友,没有认真看贴,直接给出了答案。
要是 eye 坛友认真看帖的话,我想这个谜题,没这么容易解开,
你还是得继续不得骑姐。

出0入8汤圆

发表于 2017-1-14 14:30:53 | 显示全部楼层
zxq6 发表于 2017-1-14 14:27
谢谢提醒。我的mdk版本是4.73,应为没有升级的理由,所以一直沿用着。看来跟编译环境也有很大关系?
不过 ...

以前用低版本的keil的时候从不敢写逻辑复杂的语句,经常会遇到错误。

截图中的形参也没有定义成const型,还是可以运行通过的。应该是跟版本有关。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入8汤圆

发表于 2017-1-14 14:36:21 | 显示全部楼层
lw2012 发表于 2017-1-14 14:30
以前用低版本的keil的时候从不敢写逻辑复杂的语句,经常会遇到错误。

截图中的形参也没有定义成const型 ...

他传进的实参,是 const 的,没有特殊原因的话,会被放置在 RO 段,也就是代码区,
是不可修改的。

出0入8汤圆

发表于 2017-1-14 14:41:36 | 显示全部楼层
security 发表于 2017-1-14 14:36
他传进的实参,是 const 的,没有特殊原因的话,会被放置在 RO 段,也就是代码区,
是不可修改的。 ...

呃,对对对, *pf++ = c;这句犯法了,对只读代码进行了写操作。

出0入8汤圆

发表于 2017-1-14 14:49:05 | 显示全部楼层
你要感谢的,不止是 15 楼。
要感谢 15 楼的不认真看帖,其实答案在 15 楼之前,就已经出现了。

出0入8汤圆

发表于 2017-1-14 15:12:30 | 显示全部楼层
security 发表于 2017-1-14 14:49
你要感谢的,不止是 15 楼。
要感谢 15 楼的不认真看帖,其实答案在 15 楼之前,就已经出现了。 ...

哈哈,这就是所谓的“古二真”

出0入8汤圆

发表于 2017-1-14 15:14:51 | 显示全部楼层
lw2012 发表于 2017-1-14 15:12
哈哈,这就是所谓的“古二真”

关键是楼主位,末尾写了这么一句:
经过15楼的指导,最终解决了这个问题。再次谢谢15楼。

出0入22汤圆

 楼主| 发表于 2017-1-14 15:59:21 | 显示全部楼层
security 发表于 2017-1-14 15:14
关键是楼主位,末尾写了这么一句:
经过15楼的指导,最终解决了这个问题。再次谢谢15楼。 ...

改了,改了,谢谢您的批评。

出0入0汤圆

发表于 2017-1-14 16:09:58 | 显示全部楼层
zxq6 发表于 2017-1-14 15:59
改了,改了,谢谢您的批评。

所以我11楼让你看expr的地址是多少(字符串是在RAM区,还是在ROM区)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 21:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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