1

I got some problems when I call json_decref()

#include <jansson.h>
#include <stdio.h>

void main()
{
    json_t *aa, *bb, *cc, *dd;

    aa = json_load_file ("/home/cuihaikuo/demo.json", JSON_STRICT, NULL);
    bb = json_array_get (aa, 0); 
    if (bb != NULL) 
        json_decref (bb);
    if (aa != NULL)
        json_decref (aa);

}

I use vargrind running the program, it says Invalid write of size 8

==2641== Invalid write of size 8
==2641==    at 0x4E4201A: json_delete (in /usr/lib/x86_64-linux-gnu/libjansson.so.4.7.0)
==2641==    by 0x4006C3: json_decref (in /home/cuihaikuo/chk/test/a)
==2641==    by 0x400721: main (in /home/cuihaikuo/chk/test/a)
==2641==  Address 0x5412438 is 8 bytes inside a block of size 48 free'd
==2641==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2641==    by 0x4006C3: json_decref (in /home/cuihaikuo/chk/test/a)
==2641==    by 0x40070E: main (in /home/cuihaikuo/chk/test/a)

if I comment out json_decref (aa);, it will lead a memory leak, how to explain it and what should I do?

cuihaikuo
  • 105
  • 1
  • 8

1 Answers1

1

json_array_get() returns a borrowed reference. You must not call json_decref() on the values that are returned as borrowed references, unless you manually call json_incref() to increase the reference count. In your minimalistic example, this is not required, so remove the json_decref (bb); and the code should work as expected.

However, if you need to use bb after you have released aa, then call json_incref (bb); after bb = json_array_get (aa, 0); and later, when you are done using bb, you can call json_decref (bb);

Also, even though json_array_get() doesn't mind being passed a NULL value, it would be nice to check the value of aa before using it, so readers of your code doesn't have to double check the manual to see if it is OK not to check aa before using it in json_array_get().

Erki Aring
  • 1,736
  • 10
  • 13