【问题标题】:How to free json_object?如何释放 json_object?
【发布时间】:2013-02-14 16:54:10
【问题描述】:

我有以下代码

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>

#include <json/json.h>

int main(int argc, char **argv)
{
      json_object *new_obj;
      char buf[] = "{ \"foo\": \"bar\", \"foo2\": \"bar2\", \"foo3\": \"bar3\" }";
      new_obj = json_tokener_parse(buf);
      .....
      json_object_put(new_obj);
}

json_object_put(new_obj) 是否释放与new_obj 相关的所有内存?

【问题讨论】:

    标签: c json libjson


    【解决方案1】:

    来自文档:

    void json_object_put    (struct json_object *this)  
    

    减少json_object的引用计数,如果达到零则释放

    来源: http://oss.metaparadigm.com/json-c/doc/html/json__object_8h.html

    【讨论】:

    • 我知道这一点。我正在寻找确认 json_object_put 在我放置的示例中释放 meomry
    • 所以你问如何验证释放的内存实际上是释放的?这是一个完全不同的问题。
    • 我也发现这是一个有趣的问题。函数名出乎意料……我没有直观的理解,“put”是指递减引用计数,需要时释放。
    • json_object_put 是释放嵌套对象,还是我们需要为所有嵌套对象调用它?
    • json_object_put 递归工作;如果所有嵌套对象的引用计数都为 1(常见情况),那么它将释放它们。但是,如果您从主对象中提取了一个子树并显式增加了它的引用计数,那么该层次结构将继续存在,直到您对其调用 json_object_put。
    【解决方案2】:

    您必须了解该库的工作原理。

    json_tokener_parse() 是第一个,它创建了一个对象,该对象将充当内存管理父对象,从它创建的所有对象都使用该对象来访问它们定义的数据。

    因此,如果您一直为字符串字段创建 char *str,则该字段实际上并不存储字符串,而是从 json_tokener_parse() 返回的原始对象。

    这就是你不能只使用普通的 free() 并期望它像 char 数组或其他东西一样工作的原因。

    为了安全起见,不要使用 json_tokener_parse_ex() 函数,因为您还必须释放作为标记器的对象,而使用 json_tokener_parse() 您不需要该参数。

    除此之外,要安全地关闭所有内容,只需执行以下操作:

    while (json_object_put(orig_object) != 1) {
      // keep freeing
    }
    

    您应该只需要这样做一次,但库可能会改变。

    【讨论】:

    • 这是一个糟糕的建议。 json_tokener_parse_ex() 没有什么“不安全”的地方,你绝对应该在循环中调用 json_object_put。
    • 埃里克,你的理想有问题。显然这在理想情况下是正确的,但是对于这个库,您需要了解令牌的免费例程确实存在内存泄漏,最终会失败。你肯定还是不了解编译器。测试循环中命令输出的 while 循环仅在需要时运行,它是执行操作的理想方法,因为函数失败或成功会停止循环,因为它使用有符号整数,而不是无符号整数返回值。你无法在数学上打败它,我不知道你为什么抱怨。
    • 编译器? malloc 和免费的?图书馆 API 的规则?他们都是一样的,对吧?我想因为我认为它们不同,所以我不能“理解编译器”。所以,继续,不分青红皂白地调用 json_object_put,当你在它的他内存块上调用 free 几十次,并确保之后继续访问这些块,我相信一切都会好起来的。 /s 请停止散布关于不存在内存泄漏的谎言。
    • 是的,编译器根据 put() 函数中的代码将 while 循环转换为绝对非 while 循环。毫无疑问,它绝对不会失败。
    猜你喜欢
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 2011-09-15
    • 2011-05-03
    • 2010-10-16
    • 2017-12-21
    • 1970-01-01
    相关资源
    最近更新 更多