你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

sprintf使用的奇怪现象,怀疑for循环控制变量有BUG

[复制链接]
kylongmu 提问时间:2017-7-26 22:44 /
本帖最后由 kylongmu 于 2017-7-28 12:56 编辑

使用平台NUCLEO 767ZI以下代码
printf.jpg
现象描述,当调用100次以后,第二个printf会被执行到。把字符数组大小改为200后,调用200次后,第二个printf有打印输出。测试几组数组大小,均出现严格的错误现象。
目前怀疑sprintf函数影响,或者是for循环体导致循环变量i在离开for结构后被不正确的置零了。
------------------------------------------------
工程生成:
CUBEMX 4.22
------------------------------------------------问题已解决:FreeRTOS默认线程里的Stack size是128字节,我的程序是放到线程里的,估计是变量申请越界了,调整此处Stack size 到256字节问题解决。
前面一个CDC主机找不到设备的问题,感谢act8238建议加大Heap size解决。
也感谢moyanming2013对我程序中问题的挑剔,toofree的热心帮忙。
总结一下:CubeMX以及FreeRTOS为了突出性能,空间占用小,默认设置的Heap与Stack尺寸很小,必须小心,尤其是当使用USB,sprintf这类会动态申请空间的库时。而出错的现象却很难定位。





收藏 1 评论38 发布时间:2017-7-26 22:44

举报

38个回答
七哥 回答时间:2017-7-28 02:43:25
提一点意见。

楼主,老改主楼帖子,这样不好。
帖子错了,可以往上加,备注一下什么时间修改过什么东西。
你这样老改,让其它人看到回复的楼层,不知道怎么回事。换种说法,你这样是对回复你帖子和看你帖子人的不尊重。
anobodykey 回答时间:2017-7-27 09:32:44
楼上正解,你的char * Dbg_QMsg[100]是指针数组,即有100个数组,每个里面都是一个指针,你100的时候Qmsg就已经溢出了
Dandjinh 回答时间:2017-7-27 09:16:30
试一下把 char * Dbg_QMsg[100]; 改为 char Dbg_QMsg[100]; 看看
kylongmu 回答时间:2017-7-26 22:56:04
本帖最后由 kylongmu 于 2017-7-27 17:21 编辑

kylongmu 回答时间:2017-7-26 23:15:18
检查发现,当循环到缓冲区大小时,字符串的第一个字符会被sprintf打印为'\0',而puts是以'\0'为输出结束的,为啥会这样呢?
kylongmu 回答时间:2017-7-27 00:43:48
本帖最后由 kylongmu 于 2017-7-27 17:22 编辑

改正语法错误,现象依旧,换代码测试定位问题,
目前测试sprintf的内容没有问题,看来是for循环里的变量i有问题,另外一组代码来做测试:
char Dbg_QMsg[100];
uint8_t P_msg1[]="Err\n\r";
        sprintf(Dbg_QMsg,"Hello %d\n\r\0",i);
        for(i=0;i<100;i++)
        {
                if(Dbg_QMsg【i】=='\0')//不用中文括号,这里无法显示
                {
                        if(i==0)
                                HAL_UART_Transmit(&huart3, P_msg1,sizeof(P_msg1), 0xFFFF);//不会执行
                        break;
                }
        }
        if(i==0)
                HAL_UART_Transmit(&huart3, P_msg1,sizeof(P_msg1), 0xFFFF);//会执行到
在for循环体内i不会等于0,但是循环体外在循环字符分配大小次数后,i就会变为0,而且是在循环数大于等于字符数组分配空间的情况下才会出现。
wuqt 回答时间:2017-7-27 08:54:44
改一下类似iar里的library options的优化参数试试,标准库一般不会有问题的。
MrJiu 回答时间:2017-7-27 09:11:51
百度一下sprintf,有惊喜哦!!!
kylongmu 回答时间:2017-7-27 09:38:55
本帖最后由 kylongmu 于 2017-7-27 17:20 编辑

多谢各位大神的意见。
我用的是CubeMX生成的keil工程,目前可以确认的是编译优化等级从o1到o3,都出现相同的状况,就是for循环体外变量被置零,而且是根据设置的缓冲区大小决定循环次数。
keil里面用的是5.06版本的编译器,还有个6.4编译器,可是一换6.4就一堆错误出来,无法编译,看来目前的CubeMX还没有更新支持keil的新编译器,关于这点各位有什么建议。
char Dbg_QMsg[100];
uint8_t P_msg1[]="Err\n\r";
        sprintf(Dbg_QMsg,"Hello %d\n\r\0",i);
        for(i=0;i<100;i++)
        {
                if(Dbg_QMsg【i】=='\0')//不用中文括号,这里无法显示
                {
                        if(i==0)
                                HAL_UART_Transmit(&huart3, P_msg1,sizeof(P_msg1), 0xFFFF);//不会执行此处
                        break;
                }
        }
        if(i==0)
                HAL_UART_Transmit(&huart3, P_msg1,sizeof(P_msg1), 0xFFFF);//会执行此处
也就是说变量i一旦出了for循环体就被置零了,而且这种现象是循环次数达到Dbg_QMsg[100]分配的大小数来决定的,如果循环99次以内,出了for,i并不会变0;一旦大于等于100,出了for后i就会被置零;奇怪的是把空间分配为200的数组,那么问题点就变成199了。
另外char Dbg_QMsg[100]不论是申明为全局,还是局部变量,还是static,还是volatile,结果都一样。
wuqt 回答时间:2017-7-27 10:29:09
kylongmu 发表于 2017-7-27 09:38
多谢各位大神的意见。
我用的是CubeMX生成的keil工程,目前可以确认的是编译优化等级从o1到o3,都出现相同 ...

不是那个编译优化,是iar 里 project-options-general options - library options,针对 printf scanf 库的优化!
如果仍不行可以在win32里编译运行测试下,找找问题!
moyanming2013 回答时间:2017-7-27 11:41:05
anobodykey 发表于 2017-7-27 09:32
楼上正解,你的char * Dbg_QMsg[100]是指针数组,即有100个数组,每个里面都是一个指针,你100的时候Qmsg就 ...

我去,楼主都视而不见7楼和8楼吗!!
这明显是语法问题不是什么bug,sprintf面世的时间可能比楼主年龄都大:
永远先从自身找问题!
me浩 回答时间:2017-7-27 11:47:25
kylongmu 回答时间:2017-7-27 13:15:05
本帖最后由 kylongmu 于 2017-7-27 13:17 编辑
moyanming2013 发表于 2017-7-27 11:41
我去,楼主都视而不见7楼和8楼吗!!
这明显是语法问题不是什么bug,sprintf面世的时间可能比楼主年龄都 ...

看我7楼的回复,改了那个语法错误一样的。前面回复咋被吃掉了,刷新不出来?
moyanming2013 回答时间:2017-7-27 13:59:04
kylongmu 发表于 2017-7-27 00:43
改正语法错误,现象依旧,换代码测试定位问题,
目前测试sprintf的内容没有问题,看来是for循环里的变量i有 ...

1.i是什么类型的?注意最大值越位问题。
2.你这种在for循环里面加if判断Dbg_QMsg数组时,当i为100时就直接死机了!还是你的代码有问题!
QUEUE_MESSAGE_MAX_SIZE也不知道是多少?!
3.确保其它代码无问题?逻辑实现无问题?
通过此前以及现在你的代码看,还是多查找自己的原因,别一上来就说这bug那bug,自己没bug?!
七哥 回答时间:2017-7-27 13:59:22
把你的puts()函数,拉出来遛遛
123下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版