問題記錄:
/************************************************|
* 描述: 將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 版本。
-