3

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

所以看了网上的一些信息,我看到了这个帖子json_object_new_object

所以我有2个问题要弄清楚:第一个是关于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??

根据这篇文章,它似乎没问题,但还没有真正得到回答。

问题 2:看这个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);
4

1 回答 1

3

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返回的对象(即,除非您将其合并到另一个对象或数组中,如前所述)。

在引用的博客文章中编写代码的人似乎并不关心他的程序中的内存泄漏,这可能是因为该程序非常简单,并且在只处理一个对象后立即结束。

于 2019-01-15T15:56:42.110 回答