问题记录:
/************************************************|
* 描述: 将ID124执行NFC操作-JSON解析为结构体* 函数名: cJSON_ID124_to_struct* 参数[ I]: *json_string 待解析的指针* 参数[II]: *wireless_rxd 结构体指针* 返回: 成功返回0 失败返回-1************************************************/
int cJSON_ID124_to_struct(const char *json_string, WIRELESS_RXD *wireless_rxd)
{if (!json_string || !wireless_rxd) {#ifdef DEBUGprintf("Invalid input parameters\n");#endifreturn -1;}cJSON *root = cJSON_Parse(json_string);if (!root) {#ifdef DEBUGprintf("JSON parse error: [%s]\n", cJSON_GetErrorPtr());#endifreturn -1;}cJSON *object = cJSON_GetObjectItem(root, "124");if (!object) {#ifdef DEBUGprintf("Missing '124' object\n");#endifcJSON_Delete(root);return -1;}// 解析NFC操作类型 (必需字段)cJSON *item = cJSON_GetObjectItem(object, "1");if (!item) {#ifdef DEBUGprintf("Missing or invalid '1' field (NFC action)\n");#endifcJSON_Delete(root);return -1;}wireless_rxd->NfcAction.nfc_action = item->valueint;// 如果不是添加实体卡操作,则解析卡IDif (wireless_rxd->NfcAction.nfc_action != NFC_ADD_ENTITY) {item = cJSON_GetObjectItem(object, "2");if (!item) {#ifdef DEBUGprintf("Missing or invalid '2' field (NFC ID)\n");#endifcJSON_Delete(root);return -1;}wireless_rxd->NfcAction.nfcID = (uint32_t)(item->valuedouble);}// 解析用户ID (必需字段)item = cJSON_GetObjectItem(object, "4");if (!item) {#ifdef DEBUGprintf("Missing or invalid '4' field (user ID)\n");#endifcJSON_Delete(root);return -1;}wireless_rxd->NfcAction.userId = item->valueint;/*更新备份值*/if (RTC_BKP10 != wireless_rxd->NfcAction.userId) {RTC_BKP10 = wireless_rxd->NfcAction.userId;}cJSON_Delete(root);return 0;
}/*函数解析多次json_string={"124":{"1":4,"2":3012238756,"4":134}}后陷入奔溃*/
函数在多次解析相同的 JSON 字符串 {"124":{"1":4,"2":3012238756,"4":134}}
后会崩溃并返回 "JSON parse error",这可能有以下几个原因:
可能的原因
-
内存泄漏:
-
每次调用
cJSON_Parse()
都会分配内存,虽然调用了cJSON_Delete(root)
,但可能在多次调用后仍然有内存未被正确释放。
-
-
多线程问题:
-
如果此函数在多线程环境中被调用,而 cJSON 不是线程安全的,可能会导致问题。
-
-
浮点数精度问题:
-
使用
item->valuedouble
来读取 NFC ID,但将其强制转换为 uint32_t,对于大整数可能会有精度问题。
-
-
输入字符串被修改:
-
原始 JSON 字符串可能在解析过程中被其他代码修改。
-
-
cJSON 库内部状态问题:
-
某些 cJSON 版本可能有内部状态管理问题。
-
解决方案建议
-
添加更详细的错误日志:
#ifdef DEBUG printf("JSON string to parse: %s\n", json_string); const char *error_ptr = cJSON_GetErrorPtr(); if (error_ptr) {printf("Error before: %s\n", error_ptr); } #endif
-
检查输入字符串有效性:
if (!json_string || strlen(json_string) == 0) {#ifdef DEBUGprintf("Empty or NULL JSON string\n");#endifreturn -1; }
-
修改 NFC ID 解析方式:
// 改为使用字符串形式读取大整数,避免精度问题 item = cJSON_GetObjectItem(object, "2"); if (item && item->valuestring) {wireless_rxd->NfcAction.nfcID = (uint32_t)strtoul(item->valuestring, NULL, 10); } else if (item) {wireless_rxd->NfcAction.nfcID = (uint32_t)item->valueint; } else {// 错误处理 }
-
确保线程安全:
-
如果多线程使用,添加互斥锁保护 cJSON 解析过程。
-
-
检查内存使用:
-
使用内存检测工具检查是否有内存泄漏。
-
-
验证 cJSON 版本:
-
确保使用的是最新稳定的 cJSON 版本。
-