我是否必须释放json_tokener_parse返回的json_object?

时间:2019-01-15 15:30:56

标签: json-c

我正在C应用程序中尝试内存错误,并使用valgrind,我在json-c库周围看到了许多奇怪的东西。

因此,在网络上查看一些信息,我看到了关于json_object_new_object的{​​{3}}

所以我有两个问题要弄清楚: 第一个关于json构造

当我将一个对象添加到另一个对象时,是否必须只释放第一个对象? 例如:

json_object * jobj1 = json_object_new_object();
json_object * jobj2 = json_object_new_object();

json_object_object_add(jobj1,"Object", jobj2);

...

json_object_put(jobj); // Is it enough to free all the json tree??

根据此post,这似乎还可以,但尚未得到真正的答案。

问题2: 看着这个post,似乎没有必要释放任何东西,而是看着我的valgrind日志,json_object_new_object被称为:

by 0x4F7F4CF: json_object_new_object (in /lib/x86_64-linux-gnu/libjson-c.so.3.0.1)
by 0x4F81B38: json_tokener_parse_ex (in /lib/x86_64-linux-gnu/libjson-c.so.3.0.1)
by 0x4F82316: json_tokener_parse_verbose (in /lib/x86_64-linux-gnu/libjson-c.so.3.0.1)
by 0x4F8237D: json_tokener_parse (in /lib/x86_64-linux-gnu/libjson-c.so.3.0.1)

所以我必须这样做吗?

json_object *jobj = json_tokener_parse(...);

...

json_object_put(jobj);

1 个答案:

答案 0 :(得分:1)

json_object_new_object的文档中说

  

请记住,当使用json_object_object_add或json_object_array_put_idx时,所有权将转移到对象/数组。

  

您获得但未转让的所有所有权必须通过json_object_put释放。

对我来说,这应该可以:

json_object *jobj1 = json_object_new_object();
json_object *jobj2 = json_object_new_object();

json_object_object_add(jobj1, "Object", jobj2);

// ...

json_object_put(jobj1); // This is the only one we have ownership of now

是的,就像文档中所说的那样,您必须使用json_object_put释放所有所有权。

关于json_tokener_parse,文档没有明确说明所有权或发布权,但是如果在这方面与json_object_new_object不同,我会感到非常惊讶。如果不允许您使用从json_tokener_parse返回的对象的方式与使用通过json_object_new_object构造的对象的方式一样,那就没有任何意义。

例如,应该可以这样做:

json_object *jobj1 = json_object_new_object();  // "Manual" object
json_object *jobj2 = json_tokener_parse(...);   // Parsed object

// At this point, jobj1->_ref_count and jobj2->_ref_count will both be 1.

// We could now add the parsed object as a new field in our "manual" one:
json_object_object_add(jobj1, "ParsedObject", jobj2); 

// ...

// In the end, we only have to release the "manual" object.
json_object_put(jobj1);

此外,是的,正如您的valgrind日志所指示的那样,json_tokener_parse函数在幕后调用json_object_new_object,因此您需要为返回的对象调用json_object_put(即,除非合并了如前所述,将其放入另一个对象或数组。

在引用的blog post中编写代码的人似乎并不关心程序中的内存泄漏,可能是因为该程序是如此简单,并且仅在处理了一个对象后立即结束。