(求助)续[[STM32F7通过ESP8266获得网络时间和天气]]内存管理问题

2019-07-20 02:55发布

本帖最后由 danielhuang 于 2019-3-25 21:09 编辑

http://www.openedv.com/forum.php?mod=viewthread&tid=289792&extra=
续上贴
@freethink @wcyingdream
内存管理 内存管理
经过两三天的观察,发现天气在两三个小时后就不再更新了,调用串口看接收天气信息正常,就是LCD不再更新信息。
初步估计是内存资源被耗尽所至。后面调用了内存使用率函数my_mem_perused()查看内存使用情况,便正实我了的想
法。LCD右边红 {MOD}的四位数字是内存使用率,精度是0.x%。天气程序是初始化后,每一分钟调用函数更新一次,结果内存
资源使用率就在被每次更新后上升0.5%。所以程序会在200分钟后申请不到内存而停止更新。我查看了程序,基本每个
mymalloc  都 myfree 了。现在请求大家帮助看看问题在哪里,谢谢。


//获取一次实时天气
//返回:0---获取成功,1---获取失败
u8 get_current_weather(void)
{
        u8 *p;
        u8 res;
//        u8 ipbuf[16];         //IP缓存
        p=mymalloc(SRAMIN,40);                                                        //申请40字节内存
        sprintf((char*)p,"AT+CIPSTART="TCP","%s",%s",WEATHER_SERVERIP,WEATHER_PORTNUM);    //配置目标TCP服务器
        res = atk_8266_send_cmd(p,"OK",200);//连接到目标TCP服务器
        if(res==1)
        {
                myfree(SRAMIN,p);
                return 1;
        }
        delay_ms(300);
        atk_8266_send_cmd("AT+CIPMODE=1","OK",100);      //传输模式为:透传       
//        atk_8266_get_wanip(ipbuf);//获取WAN IP

        USART3_RX_STA=0;
        atk_8266_send_cmd("AT+CIPSEND","OK",100);         //开始透传
        printf("start trans... ");
        u3_printf("GET https://api.seniverse.com/v3/wea ... =zh-Hans&unit=c ");       
        delay_ms(20);//延时20ms返回的是指令发送成功的状态
//        atk_8266_at_response(1);
        USART3_RX_STA=0;        //清零串口3数据
        delay_ms(1000);
//        atk_8266_at_response(0);
        if(USART3_RX_STA&0X8000)                //此时再次接到一次数据,为天气的数据
        {
                USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
        }
        parse_now_weather();

       
        atk_8266_quit_trans();//退出透传
        atk_8266_send_cmd("AT+CIPCLOSE","OK",50);         //关闭连接
        myfree(SRAMIN,p);
        return 0;
}


//解析当前天气
u8 parse_now_weather(void)
{
        cJSON *root;
        cJSON *pSub;
        cJSON *arrayItem;
        cJSON *pItem;
        cJSON *pSubItem;
        cJSON *pChildItem;
       
        char *pr,*utf8str,*gbkstr;
//        u8 size = 0;
        int len;
        u8 res;
        u8 temperature;
       
        root = mymalloc(SRAMIN,sizeof(cJSON));
        pSub = mymalloc(SRAMIN,sizeof(cJSON));
        pItem = mymalloc(SRAMIN,sizeof(cJSON));
        pSubItem = mymalloc(SRAMIN,sizeof(cJSON));
        pChildItem = mymalloc(SRAMIN,sizeof(cJSON));
        arrayItem = mymalloc(SRAMIN,sizeof(cJSON));
       
        pr = mymalloc(SRAMIN,1000);
        utf8str = mymalloc(SRAMIN,50);
        gbkstr = mymalloc(SRAMIN,50);
       
        memset(pr,0,1000);
        memset(gbkstr,0,50);
        memset(utf8str,0,50);
       
        file = mymalloc(SRAMIN,sizeof(FIL));
        res=f_open(file,(const TCHAR*)APP_ASCII_5427,FA_READ);//打开文件
        if(res==FR_OK)
        {
                asc2_5427 = mymalloc(SRAMIN,file->obj.objsize);
                if(asc2_5427 != NULL)
                {
                        res = f_read(file,asc2_5427,file->obj.objsize,&br);
                }
                f_close(file);
        }

        printf("jieshou->1dayjson = %s ",USART3_RX_BUF);
       
        root = cJSON_Parse((const char*)USART3_RX_BUF);
        if(root != NULL)
        {
                pSub = cJSON_GetObjectItem(root,"results");
                if(pSub != NULL)
                {
//                        size = cJSON_GetArraySize(pSub);
                        arrayItem = cJSON_GetArrayItem(pSub,0);  
                        pr = cJSON_Print(arrayItem);   //获取jsom数组
                        pItem = cJSON_Parse(pr);       //对数组,进行升级。
                        if(pItem != NULL)
                        {
                                pSubItem = cJSON_GetObjectItem(pItem,"location");
                                if(pSubItem != NULL)
                                {
                                        pChildItem = cJSON_GetObjectItem(pSubItem,"name");
                                        if(pChildItem != NULL)
                                        {
                                                utf8str = pChildItem->valuestring;
                                                SwitchToGbk((const u8*)utf8str,strlen(utf8str),(u8 *)gbkstr,&len);  //获取城市名称转换为gbk文件
                                                Show_Str(0,0,lcddev.width,lcddev.height,(u8 *)gbkstr,32,0);         //显示城市名称。
                                          printf("定位:%s ",(u8 *)gbkstr);        //自己添加
                                        }
                                }
//                                memset(utf8str,0,50);
                                memset(gbkstr,0,50);
                                pSubItem = cJSON_GetObjectItem(pItem,"now");
                                if(pSubItem != NULL)
                                {
                                        pChildItem = cJSON_GetObjectItem(pSubItem,"text");  //获取天气信息。多云
                                        if(pChildItem != NULL)
                                        {
                                                utf8str = pChildItem->valuestring;
                                                SwitchToGbk((const u8*)utf8str,strlen(utf8str),(u8 *)gbkstr,&len);
                                                POINT_COLOR = GBLUE;
                                                Show_Str(410,40,lcddev.width,lcddev.height,(u8 *)gbkstr,32,0);  //显示多云
                                                LCD_ShowString(410,40,500,32,32,(u8*)gbkstr);
                                                printf("天气:%s ",(u8 *)gbkstr);        //自己添加
                                        }
//                                        memset(utf8str,0,50);
//                                        memset(gbkstr,0,50);
                                       
                                        pChildItem = cJSON_GetObjectItem(pSubItem,"code");              //获取气象代码
                                        if(pChildItem != NULL)
                                        {
                                                gbkstr = pChildItem->valuestring;
                                                show_weather_icon((u8 *)gbkstr,0);                           //根据气象代码,更新图片
                                        }
//                                        memset(gbkstr,0,50);
                                       
                                        pChildItem = cJSON_GetObjectItem(pSubItem,"temperature");     //获取温度信息
                                        if(pChildItem != NULL)
                                        {
                                                gbkstr = pChildItem->valuestring;
                                                temperature = str2int((u8 *)gbkstr);
                                                gui_show_num(280,90,2,RED,54,temperature,0x80);
                                                gui_show_num(610,90,4,RED,54,my_mem_perused(SRAMIN),0x80);
                                                printf("温度:%s ",(u8 *)gbkstr);        //自己添加
                                        }
                        }
               
                        pSubItem = cJSON_GetObjectItem(pItem,"last_update");
                                if(pSubItem != NULL)               
                                {
                                  gbkstr =pSubItem->valuestring;
                                        POINT_COLOR = WHITE;
                                         LCD_ShowString(0,188,300,12,12,(u8*)gbkstr);
                                         printf("最后更新时间: %s ",(u8*)gbkstr);
                                        //LCD_ShowString(60,110,200,16,16,"Font Update Success!");
                                }               
                        }
                        cJSON_Delete(pItem);
                        myfree(SRAMIN,pItem);
                }
        }
        cJSON_Delete(root);
        myfree(SRAMIN,root);
        myfree(SRAMIN,pSub);
        myfree(SRAMIN,pItem);
        myfree(SRAMIN,pSubItem);
        myfree(SRAMIN,pChildItem);
        myfree(SRAMIN,arrayItem);
        myfree(SRAMIN,pr);
        myfree(SRAMIN,utf8str);
        myfree(SRAMIN,gbkstr);
        myfree(SRAMIN,file);
        myfree(SRAMIN,asc2_5427);
        return 0;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
danielhuang
1楼-- · 2019-07-21 02:39
正点原子 发表于 2019-3-28 02:00
不对,这不会导致内存泄漏

会啊,跟这情况是一样的。
https://blog.csdn.net/qq_32319583/article/details/53641469
QQ截图20190328103922a.jpg
QQ截图20190328104132b.jpg
正点原子
2楼-- · 2019-07-21 08:39
danielhuang 发表于 2019-3-28 10:41
会啊,跟这情况是一样的。
https://blog.csdn.net/qq_32319583/article/details/53641469

你说的这个,根本不是一回事。
如果内存管理,连你申请300个,只用了30个字节,就导致270个泄漏,那就是天大的笑话了。
wlq390934605
3楼-- · 2019-07-21 13:19
 精彩回答 2  元偷偷看……
wlq390934605
4楼-- · 2019-07-21 17:36
不但不能没释放就申请,更不能申请之后却忘记申请之后内存地址的保存位置, 对于单向申请,单向释放的内存更加需要注意,比如给某某发消息,收信方必需释放;
danielhuang
5楼-- · 2019-07-21 22:45
 精彩回答 2  元偷偷看……
danielhuang
6楼-- · 2019-07-22 03:06
 精彩回答 2  元偷偷看……

一周热门 更多>