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

 

 

  • 40
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
在 UC/OS-II 中使用 cJSON 时,你可以配置动态内存管理器来分配和释放 cJSON 对象所需的内存。以下是一种可能的方式来配置动态内存管理器: 1. 在你的 UC/OS-II 项目中,定义一个全局的动态内存管理器(例如,使用堆或内存池)来分配和释放 cJSON 对象所需的内存。你可以使用 UC/OS-II 提供的内存管理函数,如 `OSMemCreate()`、`OSMemGetBlock()` 和 `OSMemPutBlock()`,或者自己实现一个内存管理器。 下面是一个使用堆来分配和释放 cJSON 对象内存的示例: ```c #include "cJSON.h" #include "os_cfg.h" #include "ucos_ii.h" #define JSON_MEM_SIZE 1024 // 定义堆大小 OS_MEM jsonMem; // 声明一个内存块对象 void YourTask(void *p_arg) { void *jsonBuf; // 创建一个内存块,用于分配 cJSON 对象的内存 OSMemCreate(&jsonMem, "JSON Memory", jsonBuf, JSON_MEM_SIZE, sizeof(cJSON), NULL); // 在任务中使用 cJSON cJSON *root = NULL; char *jsonStr = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}"; // 分配 cJSON 对象内存 root = (cJSON *)OSMemGetBlock(&jsonMem); if (root != NULL) { // 解析 JSON 字符串 root = cJSON_Parse(jsonStr); if (root != NULL) { // 其他操作... // 释放 cJSON 对象内存 OSMemPutBlock(&jsonMem, root); } } // 其他任务代码... } ``` 在上述示例中,首先定义了一个内存块 `jsonMem`,用于分配 cJSON 对象的内存。然后,在任务中使用 `OSMemGetBlock()` 函数从内存块中获取一个 cJSON 对象的内存,并在使用完后使用 `OSMemPutBlock()` 函数将其释放回内存块。 请注意,这只是一种示例配置方式,你可以根据你的需求和系统资源情况进行适当的调整和修改。 希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mrbone11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值