我必须释放 json_tokener_parse 返回的 json_object 吗?

Do I have to free json_object returned by json_tokener_parse?

我正在我的 C 应用程序中试验内存错误并使用 valgrind,我发现 json-c 库周围有很多奇怪的东西。

所以在网上查看了一些信息,我看到了这个 post 关于 json_object_new_object

所以我有两个问题要弄清楚: 第一个是关于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好像还可以,但是一直没有真正回答

问题二: 看看这个 tuto,似乎没有必要释放任何东西,但看看我的 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);

json_object_new_object 的文档说

Remember, when using json_object_object_add or json_object_array_put_idx, ownership will transfer to the object/array.

Any ownerships you acquired but did not transfer must be released through 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_object_new_object.

构造的对象那样使用从 json_tokener_parse 返回的对象,那将毫无意义

例如,应该可以这样做:

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 中编写代码的人似乎并不关心他的程序中的内存泄漏,也许是因为该程序非常简单,只处理一个对象就立即结束。