0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Janssonコード例(メモリリークなし)

Last updated at Posted at 2023-11-30

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:~# 
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?