cJSON-正確使用防止內存泄漏

主要涉及兩個釋放內存的函數:cJSON_free和cJSON_Delete,該項目在github上有如下說明:

Printing JSON

Given a tree of cJSON items, you can print them as a string using cJSON_Print.

char *string = cJSON_Print(json);

It will allocate a string and print a JSON representation of the tree into it. Once it returns, you are fully responsible for deallocating it after use with your allocator. (usually free, depends on what has been set with cJSON_InitHooks).

也就是說調用cJSON_Print(以及cJSON_PrintUnformatted)後,必須自行釋放內存,對於1.5版本及以上的cJSON可以使用cJSON_free函數,其他版本直接使用free也可,示例代碼如下:

char *json_string = cJSON_Print(item);
if (json_string) 
{
    printf("%s\n", json_string);
    cJSON_free(json_string);
}

另一段說明如下:

For every value type there is a cJSON_Create... function that can be used to create an item of that type. All of these will allocate a cJSON struct that can later be deleted with cJSON_Delete. Note that you have to delete them at some point, otherwise you will get a memory leak.
Important: If you have added an item to an array or an object already, you mustn't delete it with cJSON_Delete. Adding it to an array or object transfers its ownership so that when that array or object is deleted, it gets deleted as well. You also could use cJSON_SetValuestring to change a cJSON_String's valuestring, and you needn't to free the previous valuestring manually. 

對於cJSON_Create..形式的函數,需要使用cJSON_Delete函數釋放內存,示例代碼如下:

cJSON *json=cJSON_CreateObject();
cJSON_Delete(json);

需要注意兩個函數不能混用,否則內存無法正確釋放,目前來看除了打印的函數使用cJSON_free,其他cJSON_Create..形式的函數都使用cJSON_Delete。

此外注意上面的“Important:”部分的說明,意思是如果你把一個item添加到一個數組或者object裏,不能直接釋放item,因爲它已經包含在被添加到數組或者object裏了,刪除數組或object時被添加的item同時也會被刪除。個人試驗時發現如果釋放item後再刪除object程序將崩潰。

最後一點,如果使用cJSON_Replace..形式的函數,原來的item會被刪除,所以不必擔心原item內存泄露的問題,github說明如下

You can also replace an item in an array in place. Either with cJSON_ReplaceItemInArray using an index or with cJSON_ReplaceItemViaPointer given a pointer to an element. cJSON_ReplaceItemViaPointer will return 0 if it fails. What this does internally is to detach the old item, delete it and insert the new item in its place.

You can also replace an item in an object in place. Either with cJSON_ReplaceItemInObjectCaseSensitive using a key or with cJSON_ReplaceItemViaPointer given a pointer to an element. cJSON_ReplaceItemViaPointer will return 0 if it fails. What this does internally is to detach the old item, delete it and insert the new item in its place.

 

參考:

1. https://github.com/DaveGamble/cJSON#working-with-the-data-structure

2.https://github.com/DaveGamble/cJSON#printing-json

3.https://stackoverflow.com/questions/27394364/should-the-return-value-of-cjson-print-be-freed-by-the-caller

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章