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