cJSON memory leak
Asked Answered
C

2

3

I use cJSON in my program to convert my values to JSON and write it to file. Here is the example of my code:

void writeStructToFile(IOPipe this, struct structtype somevalues) {
    cJSON *jout = cJSON_CreateObject();
    cJSON_AddItemToObject(jout, "V1", cJSON_CreateNumber(somevalues.v1));
    cJSON_AddItemToObject(jout, "V2", cJSON_CreateNumber(somevalues.v2));
    fprintf(this->outstream, "%s", cJSON_Print(jout));
    cJSON_Delete(jout);
}

Works great, but after some time I found that Linux(embedded) kills my program because of abnormal memory use or device(on Cortex A8) just hangs. After debug I found, that leak appears exactly in this function even though I delete the pointer at the end. Could anyone see that leak?

Cloak answered 2/10, 2014 at 10:14 Comment(4)
So, does the memory leak go away when this function is empty (or when you don't call it)?Indefatigable
yes, just commented this function, checked my program with "ps" in terminal and see stable memory usage. Uncommented and see this value rising, slowly, but after 10 minutes of working it hangs the system so I cannot connect to it againCloak
Okay. What if you comment out the fprintf() line?Indefatigable
Now that what I suspected least. But you're right. Leak is in fprintf function. But why and how to fix it?Cloak
I
8

Initially I thought that it might be FILE I/O's internal buffers. But these are flushed automatically when they become too big.

The real leak is that cJSON_Print allocates memory: a char array. You must free this after you're done:

char* text = cJSON_Print(jout);
fprintf(this->outstream, "%s", text);
free(text);  // As suggested by PaulPonomarev.

cJSON_Delete(jout);
Indefatigable answered 2/10, 2014 at 12:33 Comment(4)
Ok, I've tried to add fflush after fprintf, and "\n" before(and after) writing fprintf(this->outstream, "\n%s\n", cJSON_Print(jout)); fflush(this->outstream);. Didn't help. Then I tried to write to file with descriptor instead of fprintf: int df = fileno(this->outstream); write(df, cJSON_Print(jout), sizeof(cJSON_Print(jout))); First of all - it didn't work, second - it created memory leak tooCloak
Yes! Now memory usage is stable. Only thing is when I created char* I need to use standard function free(text)Cloak
@PaulPonomarev: You also need to check that cJSON_Print doesn't return a NULL pointer. (all the cJSON functions check for NULL pointers already)Younger
Please consider changing to the cJSON_free API (see maintainers comment github.com/DaveGamble/cJSON/issues/5)Jamarjamb
N
-2

For a char* allocated cJSON_Print, it is said to use cJSON_FreePrintBuffer.

Nether answered 22/1, 2015 at 20:48 Comment(1)
Correct API is cJSON_freeJamarjamb

© 2022 - 2024 — McMap. All rights reserved.