c - 内存泄漏:通过 valgrind 扫描时可能存在内存
问题描述
通过 Valgrind 扫描我的代码时,我看到了一些随机行为。我已经释放了所有可能的内存块我仍然看到 Valgrind 说 1 个块没有正确释放。
目标:使用 cJSON.c 创建 3 级 json,然后在第二个块中修改 json 格式。
#include<stdio.h>
#include<stdlib.h>
#include"cJSON.h"
int main () {
cJSON *root = NULL, *root1 = NULL , *arrays = NULL, *array = NULL;
root = cJSON_CreateObject();
root1 = cJSON_CreateObject();
arrays = cJSON_CreateArray();
cJSON_AddItemToObject(root,"check",root1);
cJSON_AddItemToObject(root1, "innercheck",cJSON_CreateString("just to check"));
cJSON_AddItemToObject(root1, "array", arrays);
cJSON_AddItemToArray(arrays, array = cJSON_CreateObject());
cJSON_AddItemToObject(array, "innnerarray", cJSON_CreateNumber(1));
char *out = NULL;
printf("===================================================\n");
out = cJSON_Print(root);
printf("%s\n", out);
/* further operation now going to extract the value from json and readd new key */
cJSON *json_param = NULL, *exe1 = NULL , *exe2 = NULL;
json_param = cJSON_Parse(out);
exe1 = cJSON_GetObjectItem(json_param , "check");
cJSON_DeleteItemFromObject(exe1, "check");
exe2 = cJSON_CreateObject();
cJSON_AddItemToObject(exe2, "test", exe1);
char *out2 = NULL;
out2 = cJSON_Print(exe2);
printf("====================================================\n");
printf("%s\n", out2);
if(root) {
cJSON_Delete(root);
root = NULL;
}
if(json_param) {
cJSON_Delete(json_param);
json_param = NULL;
}
if(out) {
free(out);
out = NULL;
}
if(out2) {
free(out2);
out2 = NULL;
}
return 0;
}
Valgrind 扫描报告:
==23708== Memcheck, a memory error detector
==23708== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==23708== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==23708== Command: ./object
==23708==
===================================================
{
"check": {
"innercheck": "just to check",
"array": [{
"innnerarray": 1
}]
}
}
====================================================
{
"test": {
"innercheck": "just to check",
"array": [{
"innnerarray": 1
}]
}
}
==23708==
==23708== HEAP SUMMARY:
==23708== in use at exit: 64 bytes in 1 blocks
==23708==
> total heap usage: 29 allocs, 28 frees, 2,661 bytes allocated
==23708==
==23708== 64 bytes in 1 blocks are definitely lost in loss record 1 of 1
==23708== at 0x4C2FDFB: malloc (vg_replace_malloc.c:309)
==23708== by 0x108F47: cJSON_New_Item (cJSON.c:214)
==23708== by 0x10C9F8: cJSON_CreateObject (cJSON.c:2410)
==23708==
> by 0x108BFA: main (object.c:35)
==23708==
==23708== LEAK SUMMARY:
==23708== definitely lost: 64 bytes in 1 blocks
==23708== indirectly lost: 0 bytes in 0 blocks
==23708== possibly lost: 0 bytes in 0 blocks
==23708== still reachable: 0 bytes in 0 blocks
==23708== suppressed: 0 bytes in 0 blocks
==23708==
==23708== For lists of detected and suppressed errors, rerun with: -s
==23708== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
我已经释放了所有可能的内存块,但无法理解为什么我仍然得到 1 个块没有正确释放。
解决方案
您的代码中似乎有两个问题。
首先,您需要在退出之前释放exe2
对象(您已使用 分配)。cJSON_CreateObject()
cJSON_Delete(exe2);
其次......您需要在将对象添加到对象之前将其分离。否则,当您调用时,您将获得双重释放- 库将尝试释放同一对象两次(因为同一对象将作为子对象附加到多个对象)。check
json_param
exe2
cJSON_Delete(exe2)
所以改变
exe1 = cJSON_GetObjectItem(json_param, "check");
cJSON_DeleteItemFromObject(exe1, "check");
简单地
exe1 = cJSON_DetachItemFromObject(json_param, "check");
请注意,我删除了该行cJSON_DeleteItemFromObject(exe1, "check");
- 因为据我所知它是多余的(除非您打算删除该innercheck
元素)。
推荐阅读
- xamarin - 应用程序在 UWP 中的 Windows 应用程序认证工具包中的验证应用程序中没有进展?
- python - 如何使用 Python 从 2 个 excel 中获取额外和遗漏的数据
- android - 停止处理程序线程
- ruby-on-rails - 编辑帖子时,我的照片字段不保存选择
- python-3.x - 我可以使用具有不同输入张量的相同模型吗?我应该避免多次运行 session.run() 吗?
- excel - 如何从excel文件中填写下拉列表
- c# - c# flags 属性枚举位组合如何工作?
- sql - Postgres日期问题
- c++ - 使用 C++ 和 Jsoncpp 从 AWS S3 解析 json 文件
- c - C: AF_UNIX 套接字上的剩余字节