代码之家  ›  专栏  ›  技术社区  ›  fralbo

我必须释放json_tokener_parse返回的json_对象吗?

  •  0
  • fralbo  · 技术社区  · 6 年前

    我正在测试我的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 看起来还可以,但还没有得到真正的答复。

    问题2: 看着这个 tuto 似乎没有必要释放任何东西,只需要看一下我的Valgrind日志, json_object_new_对象 被称为:

    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 回复  |  直到 6 年前
        1
  •  0
  •   mbj    6 年前

    文件 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_对象 .

    例如,应该可以这样做:

    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标记器分析 函数调用 json_object_new_对象 在幕后,所以你需要打电话 JSON-ObjutoPoT 对于返回的对象(即,除非您将其合并到另一个对象或数组中,如前所述)。

    在引用文件中编写代码的人 blog post 似乎不关心程序中的内存泄漏,也许是因为该程序非常简单,只处理一个对象后立即结束。

    推荐文章