Как освободить указатель json_object после каждого вызова - PullRequest
0 голосов
/ 20 апреля 2020

Я знаю, что мы можем использовать функцию json_object_put(), чтобы освободить указатель struct json_object. Но у меня возникает проблема, когда я пытаюсь освободить указатель на эту структуру после каждого вызова функции, которая объявила и использовала ее. Программа будет Segmentation fault (core dumped) во втором итераторе while l oop, потому что я использую json_object_put(obj1); в test_json функции.

#include <stdio.h>
#include <stdlib.h>
#include <json-c/json.h>
struct json_object * parse_object;
void init() {

    char buffer_file[] = "{ \"object\": {\"array1\": [1, 2, 3], \"array2\": [4, 5, 6] } }";
    parse_object = json_tokener_parse(buffer_file);

}
void test_json() {
    struct json_object * obj1, * arr1;
    json_object_object_get_ex(parse_object, "object", &obj1);
    json_object_object_get_ex(obj1, "array1", &arr1);
    int size = json_object_array_length(arr1);
    printf("size = %d \n", size);
    json_object_put(obj1);  
}

int main(int argc, char const *argv[]) {
    int j = 0;
    int max = 4;
    init();
    while(++j < max) {
       test_json();
    }
    json_object_put(parse_object);
    return 0;
}

Я могу использовать только json_object_put(parse_object); в основной функции, чтобы освободить все json_object но если я увеличу значение max до огромного (например, 1000000), то утечка памяти станет очень большой, прежде чем я вызову json_object_put(parse_object);.

Так что, в этом случае, как можно освободить json_object (obj1) (parse_object всегда глобальная переменная)? Если это невозможно, пожалуйста, дайте другое решение для получения информации из файла json в c.

Ссылка для документа struct json_object

Ответы [ 2 ]

2 голосов
/ 20 апреля 2020

В соответствии с примером на GitHub Json - C, документация которого, я должен признать, не очень ясна, кажется, что

int json_object_put(struct json_object *jso);

никогда не вызывается , когда struct json_object получен посредством вызова json_tokener_parse(). Это скорее используется, когда он был получен через один из этих вызовов

jobj = json_object_new_object();
res  = json_object_new_array();

Это заставляет меня думать, что с

int test_json() {
    struct json_object * obj1, * arr1;
    json_object_object_get_ex(parse_object, "object", &obj1);
    /* ... */
    json_object_put(obj1);
    return size;   
}

каким-то образом вы освободили всю выделенную память с помощью json_object_put(obj1); потому что obj1 был единственным объектом, который должен быть освобожден, и ничего не осталось в parse_object.

Моя гипотеза состоит в том, что json_object_put(obj1); из всех объектов, полученных с json_tokener_parse(), один за другим, является альтернативным на один вызов json_object_put(parse_object); в конце.

@ mattefrank анализ подтверждает эту гипотезу.

2 голосов
/ 20 апреля 2020

Как вы на самом деле знаете, что есть утечка памяти? Когда я запускаю ваш пример с valgrind без использования json_object_put, сводка кучи всегда выглядит следующим образом (я запускаю ваш код с max = 4 и max = 1000000):

==57154== HEAP SUMMARY:
==57154==     in use at exit: 2,949 bytes in 21 blocks
==57154==   total heap usage: 32 allocs, 11 frees, 5,826 bytes allocated
==57154== 
==57154== LEAK SUMMARY:
==57154==    definitely lost: 0 bytes in 0 blocks
==57154==    indirectly lost: 0 bytes in 0 blocks
==57154==      possibly lost: 0 bytes in 0 blocks
==57154==    still reachable: 2,949 bytes in 21 blocks
==57154==         suppressed: 0 bytes in 0 blocks
==57154== Rerun with --leak-check=full to see details of leaked memory

Когда я запускаю пример только при использовании json_object_put(parse_object); вся память освобождается:

==57937== HEAP SUMMARY:
==57937==     in use at exit: 0 bytes in 0 blocks
==57937==   total heap usage: 32 allocs, 32 frees, 5,826 bytes allocated
==57937== 
==57937== All heap blocks were freed -- no leaks are possible

Примечание : я проверил с основной ветвью репозитория json - c

Также документация json - c гласит, что no количество ссылок будет изменено при вызове json_object_object_get_ex.

Какую версию делать ты используешь? Вы уже проверили проблемы на Github?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...