【问题标题】:How to free json_object pointer after each call每次调用后如何释放 json_object 指针
【发布时间】:2020-08-03 04:40:09
【问题描述】:

我知道我们可以使用函数json_object_put()来释放struct json_object的指针。但是当我在每次调用声明和使用它的函数后尝试释放指向该结构的指针时,我遇到了问题。该程序将在 while 循环的第二个迭代器中为 Segmentation fault (core dumped),因为我在 test_json 函数中使用了 json_object_put(obj1);

#include <stdio.h>
#include <stdlib.h>
#include <json-c/json.h>
struct json_object * parse_object;
void init() {

    char buffer_file[] = "{ \"object\": {\"array1\": [1, 2, 3], \"array2\": [4, 5, 6] } }";
    parse_object = json_tokener_parse(buffer_file);

}
void test_json() {
    struct json_object * obj1, * arr1;
    json_object_object_get_ex(parse_object, "object", &obj1);
    json_object_object_get_ex(obj1, "array1", &arr1);
    int size = json_object_array_length(arr1);
    printf("size = %d \n", size);
    json_object_put(obj1);  
}

int main(int argc, char const *argv[]) {
    int j = 0;
    int max = 4;
    init();
    while(++j < max) {
       test_json();
    }
    json_object_put(parse_object);
    return 0;
}

我可以在主函数中只使用json_object_put(parse_object); 来释放所有json_object,但是如果我将max 的值增大到很大(例如1000000),在我调用@ 之前泄漏内存会变得非常多987654332@.

那么,在这种情况下,如何释放json_object (obj1) (parse_object 始终是一个全局变量) 呢?如果不可能,请提供另一种从 c 中的 json 文件获取信息的解决方案。

struct json_object文档的链接

【问题讨论】:

  • 我认为我的回答和@mattefrank 的回答一起很好地分析了正在发生的事情。如果他们回答您的问题,请接受他们的回答,而不是我的,因为如果没有他们的回答,我将没有足够的信息来发布我的问题。

标签: c json memory-leaks segmentation-fault free


【解决方案1】:

你怎么知道有内存泄漏? 当我在不使用任何 json_object_put 的情况下使用 valgrind 运行您的示例时,堆摘要始终如下所示(我使用 max = 4max = 1000000 运行您的代码):

==57154== HEAP SUMMARY:
==57154==     in use at exit: 2,949 bytes in 21 blocks
==57154==   total heap usage: 32 allocs, 11 frees, 5,826 bytes allocated
==57154== 
==57154== LEAK SUMMARY:
==57154==    definitely lost: 0 bytes in 0 blocks
==57154==    indirectly lost: 0 bytes in 0 blocks
==57154==      possibly lost: 0 bytes in 0 blocks
==57154==    still reachable: 2,949 bytes in 21 blocks
==57154==         suppressed: 0 bytes in 0 blocks
==57154== Rerun with --leak-check=full to see details of leaked memory

当我只使用json_object_put(parse_object); 运行示例时,所有内存都被释放:

==57937== HEAP SUMMARY:
==57937==     in use at exit: 0 bytes in 0 blocks
==57937==   total heap usage: 32 allocs, 32 frees, 5,826 bytes allocated
==57937== 
==57937== All heap blocks were freed -- no leaks are possible

注意:我用json-c repository的master分支测试了

此外,json-c documentation 声明调用json_object_object_get_ex 时将更改no引用计数。

你用的是什么版本?您是否已经在 Github 上查看过问题?

【讨论】:

  • 谢谢。我用 valgrind 进行了测试,但没有注意 4 和 1000000 之间的差异。
【解决方案2】:

根据 GitHub Json-C 项目上的example pageexample page,我不得不承认,不是很清楚,似乎

int json_object_put(struct json_object *jso);
当通过json_tokener_parse() 调用获得struct json_object 时,

从不调用。当它通过这些调用之一获得时,它会被使用

jobj = json_object_new_object();
res  = json_object_new_array();

这让我想到了

int test_json() {
    struct json_object * obj1, * arr1;
    json_object_object_get_ex(parse_object, "object", &obj1);
    /* ... */
    json_object_put(obj1);
    return size;   
}

在某种程度上,您使用json_object_put(obj1); 释放了所有已分配的内存,因为obj1 是唯一一个被释放的对象,而parse_object 中什么也没有留下。

我的假设是,json_object_put(obj1); 在使用json_tokener_parse() 获得的所有对象中,一一替代最终对json_object_put(parse_object); 的调用。

@mattefrank 的分析证实了这一假设。

【讨论】:

  • 是的,这就是segmentation fault 的原因。在@mattefrank 的分析中,我忘记检查泄露的内存数量。谢谢
猜你喜欢
  • 1970-01-01
  • 2020-08-08
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 2019-02-22
相关资源
最近更新 更多