You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

后台运行程序比较cJSON对象时出现内存泄漏,寻求解决方法

内存泄漏问题分析与修复

泄漏原因

你的代码存在两处核心内存泄漏/野指针问题:

  • 未释放旧的prev/current对象:每次更新prev或current时,原来的对象没有调用cJSON_Delete释放,导致内存持续累积。
  • 首次运行的野指针问题:首次运行时直接将root赋值给prev,后续cJSON_Delete(root)会释放该内存,导致prev变成悬空指针,后续使用会引发未定义行为。

修复后的代码

cJSON * prev = NULL, *current = NULL;
bool compare = false;

bool compareJSON(cJSON *i,cJSON *j)
{
  if (i->type != j->type) {
        return false;
  }

  if (i->type == cJSON_Number && (i->valueint != j->valueint)) {
        return false;
  }

  if (i->type == cJSON_String && strcmp(i->valuestring,j->valuestring)){
        return false;
  }

  if (i->type==cJSON_Array)
  {
    cJSON *ic = i->child, *jc = j->child;
    while (ic && jc)
    {
      if (!compareJSON(ic, jc)) {
                return false;
        }
      ic = ic->next, jc = jc->next;
    }
    if (ic || jc) 
            return false;
  }

  if (i->type == cJSON_Object)
  {
    cJSON *ic = i->child;
    while (ic)
    {
      cJSON *jc = cJSON_GetObjectItem(j,ic->string);
      if (!jc || !compareJSON(ic,jc)){
                return false;
                }
      ic = ic->next;
    }
    cJSON *jc = j->child;
    while (jc)
    {
      cJSON *ic=cJSON_GetObjectItem(i,jc->string);
      if (!ic || !compareJSON(ic,jc)){
                return false;
            }
      jc = j->next;
    }
  }

  return true;
}

bool compareContents(){

int fd = open("/tmp/abc.txt", O_RDONLY);
char* data = (char *)malloc(st.st_size + 1); //st.st_size obtained from fstat
int n = read(fd, data, st.st_size);
data[n] = '\0';

cJSON* root = cJSON_Parse(data);
if (!root) {
    // 处理JSON解析失败的异常情况
    if (fd >= 0) close(fd);
    if (data) free(data);
    return false;
}

compare = false;
if(prev == NULL){ // 首次运行
    // 复制root对象给prev,避免root被释放后prev悬空
    prev = cJSON_Duplicate(root, 1);
}
else {
    // 释放旧的prev对象,避免内存泄漏
    cJSON_Delete(prev);
    prev = current;
}

// 释放旧的current对象,再赋值新的复制结果
if (current) {
    cJSON_Delete(current);
}
current = cJSON_Duplicate(root, 1);  

if (prev && current)
{
    compare = compareJSON(prev, current);
}

// 清理资源
if (fd >= 0)
    close(fd);
if (access("/tmp/abc.txt", F_OK) == 0 && remove("/tmp/abc.txt") != 0){
    printf("Error deleting the file\n");
}
if (data)
    free(data);
if (root)
    cJSON_Delete(root);

return compare;

}

关键修复点

  • 首次运行逻辑修正:不再直接绑定root到prev,而是通过cJSON_Duplicate复制独立对象,避免root被释放后prev成为野指针。
  • 旧对象释放逻辑:每次更新prev和current前,先调用cJSON_Delete释放旧对象,彻底避免内存泄漏。
  • 增加异常处理:新增JSON解析失败的分支,提前清理资源,防止空指针引发的崩溃。

内容的提问来源于stack exchange,提问作者bvj0412

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:01:11