0

I have a code which is always running in the background. compareContents() reads contents from a file periodically (based on an event) and stores it in a cSJON object. I have to compare current contents of the file (cJSON object) with the previous contents (again a cJSON object) everytime, but I am getting a memory leak. Please help.

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

bool compareJSON(cJSON *i,cJSON *j) /* referred from https://cjson.docsforge.com/master/api/cJSON_Compare/ */
{
  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;
    }
    // And again, for j == i.
    cJSON *jc = j->child;
    while (jc)
    {
      cJSON *ic=cJSON_GetObjectItem(i,jc->string);
      if (!ic || !compareJSON(ic,jc)){
                return false;
            }
      jc = jc->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(prev == NULL){ //first time execution of program
            prev = root;
}

else {
        if(current){
            prev = 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;

}
bvj0412
  • 17
  • 5
  • 1
    Since you seem to only be interested in the boolean "is [not] the same", why fuss with all the Json dissection? Just load the bytes from the file and then compare byte counts changing or use `memcmp()` if the byte count is the same. Less work... – Fe2O3 Oct 02 '22 at 02:48
  • 1
    An even deeper question is: Can you have the program writing the file flag when it has been updated and why? Archaeology is one thing, but... Seems a waste of resources to sift through the remnants 10's or 100's of times only to find there's been no change... – Fe2O3 Oct 02 '22 at 05:06

1 Answers1

1

I am not sure, but this seems like dynamic copy?

current = cJSON_Duplicate(root,1);

That is you never free current and prev if it was not null. Maybe start from this point? Seems like memory leak.

TheRyuTeam
  • 233
  • 1
  • 6