我正在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);
答案 0 :(得分:1)
请记住,当使用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中编写代码的人似乎并不关心程序中的内存泄漏,可能是因为该程序是如此简单,并且仅在处理了一个对象后立即结束。