例
config.json
{
"name1":"tanaka",
"name2":"suzuki",
"param": {
"name3":"sato"
}
}
- 参照:参照カウントをインクリメントして参照すること
- 借用:参照カウントを変化させずに参照すること
main.c
#include <jansson.h>
void deserialize(void)
{
json_error_t err;
// ★jsonオブジェクト作成。参照カウント:1
json_t *pJson = json_load_file("config.json", 0, &err);
// ★pJsonの一部を借用。json_decref(pObj)不要
json_t *pObj = json_object_get(pJson, "name1");
const char *name1 = json_string_value(pObj);
// ★pJsonの一部を借用。json_decref(pObj)不要
pObj = json_object_get(pJson, "name2");
const char *name2 = json_string_value(pObj);
// ★pJsonの一部を借用。json_decref(pObj)不要
pObj = json_object_get(pJson, "param");
// ★pObjの一部(pJsonの一部)を借用。json_decref(pObj)不要
pObj = json_object_get(pObj, "name3");
const char *name3 = json_string_value(pObj);
// ★pJsonを借用。json_decref(*ppObj)不要
json_t **ppObj = &pJson;
// ★jsonオブジェクトの参照カウント:0。メモリ解放
json_decref(pJson);
// ★メモリ解放後に、取得したvalueを参照するのはNG
// printf("%s\n", name1);
// printf("%s\n", name2);
// printf("%s\n", name3);
}
void serialize(void)
{
// ★jsonオブジェクト作成。参照カウント:1
json_t *pJson = json_object();
// ★参照カウンタインクリメントせず、jsonオブジェクトにキー/バリューを追加
json_object_set_new(pJson, "filename", json_string("abcdefg.txt"));
// ★jsonオブジェクト作成。参照カウント:1
json_t *pName = json_object();
// ★参照カウンタインクリメントせず、jsonオブジェクトにキー/バリューを追加
json_object_set_new(pName, "name", json_string("tanaka"));
// ★参照カウンタインクリメントせず、pJsonにpNameを追加
json_object_set_new(pJson, "object", pName);
// ★文字列を作成。メモリ解放が必要
char *output = json_dumps(pJson, json_object_size(pJson));
printf("%s\n",output);
free(output);
// ★恐らく傘下のpNameの参照カウントもデクリメントされてる。pNameの参照カウント:0?
json_decref(pJson);
}
void test(void)
{
json_t *pJson = NULL;
// ★NULLをjson_decrefに突っ込んでも問題なし
json_decref(pJson);
}
int main(void)
{
test();
deserialize();
serialize();
return 0;
}
結果
root@5c10fbf8cac1:~# ls
config.json main.c
root@5c10fbf8cac1:~# gcc -ljansson main.c
root@5c10fbf8cac1:~# ls
a.out config.json main.c
root@5c10fbf8cac1:~# valgrind --leak-check=full ./a.out
==12387== Memcheck, a memory error detector
==12387== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==12387== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==12387== Command: ./a.out
==12387==
{
"filename": "abcdefg.txt",
"object": {
"name": "tanaka"
}
}
==12387==
==12387== HEAP SUMMARY:
==12387== in use at exit: 0 bytes in 0 blocks
==12387== total heap usage: 41 allocs, 41 frees, 7,653 bytes allocated
==12387==
==12387== All heap blocks were freed -- no leaks are possible
==12387==
==12387== For lists of detected and suppressed errors, rerun with: -s
==12387== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
root@5c10fbf8cac1:~#