如何使用json_incref、json_decref和json_get查看json文件的一部分?

swvgeqrz  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(193)

我一直在努力理解如何正确使用json_decref和json_incref以及json_get函数来隔离和操作较大json文件中的一小部分,而无需将整个文件保存在内存中。这个问题是在jansson.h库和C编程语言的上下文中提出的。
我的问题是我做的对吗在下面的函数blockload中,我是否以正统的方式使用了json_incref和json_decref?我问这个问题是因为我在解析jansson documentation中关于json_incref的内容时遇到了麻烦,还有另一个posting here
我一直在努力理解如何正确使用json_decref和json_incref以及json_get函数来隔离和操作较大json文件中的一小部分,而无需将整个文件保存在内存中。这个问题是在jansson.h库和C编程语言的上下文中提出的。
我的问题是我做的对吗在下面的函数blockload中,我是否以正统的方式使用了json_incref和json_decref?我这么问是因为我在解析jansson documentation和另一个posting here中关于json_incref的内容时遇到了麻烦。
下面的代码片段读入一个名为“file.json”的文件,该文件包含以下数据

{"myarray" : [[["aaa","aab","aac"],["aba","abb","abc"],["aca","acb","acc"] ],[["baa","bab","bac"],["bba","bbb","bbc"],["bca","bcb","bcc"] ],[["caa","cab","cac"],["cba","cbb","cbc"],["cca","ccb","ccc"] ]]}

代码片段如下所示

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <jansson.h>

#define INPUTFILE "./file.json"

json_t *blockload(char *inputfile, char *blockname);

int main(void){
    
    json_error_t error;
    json_t *test;
    
    int length;
    
    const char *mystring_const;
    
    json_t *myarray;
    
    json_t *myelement;
    
    myarray = blockload(INPUTFILE, "myarray");
    
    myelement =json_array_get(json_array_get(json_array_get(myarray, 0), 0), 0);
    
    mystring_const = json_string_value(myelement);
    
    printf("%s \n", mystring_const);
    
    json_decref(myarray);
    
    return(0);
    
}
 
json_t *blockload(char *inputfile, char *blockname){
    
    json_error_t error;
    json_t *test, *myarray;
    
    test = json_load_file(INPUTFILE, 0, &error);
    
    myarray = json_object_get(test, blockname);
    
    json_incref(myarray);
    
    json_decref(test);
    
    return(myarray);
}

在本例中,我试图查看与对象“myarray”相关联的数组,但可以想象json文件有更多的片段,我不想在使用数组时将它们全部存储在内存中。我也不想用我如何加载这个感兴趣的数组的细节来弄乱主例程,所以我编写了这个函数blockload来隐藏混乱。
虽然这段代码编译并给出了我期望的答案,并且没有从valgrind产生任何问题,但我担心它可能仍然包含一些内存使用问题。所以我请求Maven们…

8oomwypt

8oomwypt1#

json_load_file()是一个对象创建函数。它返回对未指定类型的新JSON实体的所有(由调用者)引用。该实体引用计数将为1。
json_object_get()返回对指定JSON对象的指定成员的借用引用。由于您计划保留该引用,因此应该增加它的引用计数,而实际上您已经这样做了。当引用计数超过0时,将不会收集它。您可以将增加借用引用的引用计数视为将其转换为拥有引用。
在丢失对较大对象的引用之前,减少对该对象的引用计数确实是正确的做法。你没有责任知道在任何特定时间的实际引用计数,但事实上,在这种情况下,你 * 确实 * 知道,这将使该对象的引用计数减少到0,使其符合清理条件。
另一方面,您取出的数组的引用计数仍然大于零(因为您增加了它,并且在此时没有再次减少它)。因此,您可以相信该对象不会被清理。这显然是你想要达到的目的。
虽然这段代码编译并给出了我期望的答案,并且没有从valgrind产生任何问题,但我担心它可能仍然包含一些内存使用问题。
API文档并不保证JSON实体在其引用计数降到零时实际上会被清理,尽管我预计通常情况下会是这样。但即使在这种情况下推迟,Jansson也没有提供更好的选择。
在程序终止前减少数组的引用计数是干净有效的。在这样做之后,您不应该尝试进一步使用该引用,实际上您也没有这样做。
您对数组元素及其字符串值的使用也符合Jansson的规范,因此总体而言,在我看来,一切都是照本宣科的。

相关问题