其实很简单 发表于 2018-12-11 15:24:25

利用库cjson自带的函数解析

再freertos操作系统下,利用CJSON的库函数解析接收的json协议字符串。
#{"DataType":"test","Info":"{\"MIN\":\"0.101\",\"MAX\":\"1.409\"}"}$
折腾了一上午遇到两个l问题:
1.经过大约50多次解析后,函数就不能正常解析,现象是直接显示没有接收到数据。
2.查网上帖子说是因为没有释放内存,但是我加上释放内存后,会出现Error:..\FREERTOS\portable\MemMang\heap_4.c,320
Error:..\FREERTOS\portable\MemMang\heap_4.c,321这两个错误提示
哪位高手用过cjson,请赐教。
下面是代码
bool ParseCmdJson(const char* pCmdJson)
{
cJSON * pRoot = NULL,* pRoot2 = NULL;
        cJSON * pJsonNode = NULL;
        int len = 0;

        bool bRet = false;
        printf("\r\n%s \r\n",pCmdJson);
        if(strstr(pCmdJson,"#")!=NULL)
       pCmdJson=(pCmdJson+1);

          pJsonNode=pvPortMalloc(100);       
        /*Êý¾Ý°üÈ·Èϼì²é£¬*/
        pRoot = cJSON_Parse(pCmdJson);
        if(NULL == pRoot)
        {
                printf("cJSON_Parse:NULL\n");
                return bRet;
        }
       

/*Ϊ½ÓÊÕÊý¾Ý¿ª±Ù»º´æÇø*/
//        memset(pDeviceInfo, 0, sizeof(DeviceInfo));

        // ÌáÈ¡type
        pJsonNode = cJSON_GetObjectItem(pRoot, "DataType");

        if (NULL != pJsonNode)
                {
                        printf("DataType:%s\r\n" ,pJsonNode->valuestring);
                }

        pJsonNode = cJSON_GetObjectItem(pRoot, "Info");       
                                               
        if (NULL != pJsonNode)
                {
//                        printf("Info:%s\r\n" ,pJsonNode->valuestring);
                       /*½âÎöµÚ¶þ¼¶*/
                                /*Êý¾Ý°üÈ·Èϼì²é£¬*/
                                pRoot2 = cJSON_Parse(pJsonNode->valuestring);
                                if(NULL == pRoot2)
                                {
                                        printf("cJSON_Parse_2:NULL\n");
                                        return bRet;
                                }
                               
           pJsonNode = cJSON_GetObjectItem(pRoot2, "ION_MIN");       
                                if (NULL != pJsonNode)
                                {
                                        printf("ion_min:%5.3f\r\n",atof(cJSON_GetObjectItem(pRoot2, "ION_MIN")->valuestring));       
                                }               
                               
           pJsonNode = cJSON_GetObjectItem(pRoot2, "ION_MAX");       
                                if (NULL != pJsonNode)
                                {
                                  printf("ion_max:%5.3f\r\n",atof(cJSON_GetObjectItem(pRoot2, "ION_MAX")->valuestring));               
                                }                                       
                                                       
                }       
               

                cJSON_Delete(pRoot);
             vPortFree(pRoot);
                uart1_clear();
                return bRet;
}

kayatsl 发表于 2018-12-11 15:28:28

pJsonNode=pvPortMalloc(100);         多余, 很可能是你的泄露源.


cJSON_Delete(pRoot);   这个已经可以清空整个json链表了.
vPortFree(pRoot);         多余, 会造成double free.

kayatsl 发表于 2018-12-11 15:29:53

pRoot2 = cJSON_Parse(pJsonNode->valuestring);
if(NULL == pRoot2)
{
    printf("cJSON_Parse_2:NULL\n");
    return bRet;
}

另外发现你有的地方直接就return了,说好的cJSON_Delete呢?

其实很简单 发表于 2018-12-11 15:42:17

kayatsl 发表于 2018-12-11 15:28
pJsonNode=pvPortMalloc(100);         多余, 很可能是你的泄露源.




你说的pJsonNode=pvPortMalloc(100);        和vPortFree(pRoot);一开始都没有添加,只是后来发现问题才加上的。

其实很简单 发表于 2018-12-11 15:43:52

kayatsl 发表于 2018-12-11 15:29
pRoot2 = cJSON_Parse(pJsonNode->valuestring);
if(NULL == pRoot2)
{


这个return确实可能存在不合理性,再解析错误或者接受错误的时候可能会出问题

kayatsl 发表于 2018-12-11 15:53:19

解析几十次之后解不出, 通常原因确实是不够内存.

但泄露源不一定是json本身, 最好能做个内存跟踪, freertos本身有工具跟踪

trave_yang 发表于 2018-12-11 18:06:12

楼主,我之前也遇到了和你一样的问题,原因就是释放有问题,一定要保证pRoot= cJSON_Parse,和cJSON_Delete(pRoot)成对出现。
页: [1]
查看完整版本: 利用库cjson自带的函数解析