Home > Software design >  Use of json_object_put() in C library
Use of json_object_put() in C library

Time:01-21

I am using the json-c in my C program (not C ). I am getting segfaults from time to time and trying to debug. To be honest, I might not have the full understanding how the library works so I am looking for any advice.

This is partially how I am using:

char* createjsonstatusstring()
{
json_object     *jsonmain,
                *jsontmp;
const char      *conststring;
char            *string;

jsonmain = json_object_new_array();
jsontmp = json_object_new_array();
json_object_object_add(jsontmp,"test",json_object_new_string("Beispiel"));
json_object_object_add(jsontmp,"test2",json_object_new_string("Beispiel2"));
json_object_object_add(jsonmain,"Data",jsontmp);

conststring = json_object_to_json_string_ext(jsonmain,JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY); 
json_object_put(jsontmp);
json_object_put(jsonmain);

string = malloc(strlen(conststring) 1);
strcpy(string,conststring);
return string;
}

When doing the last json_object_put I am getting the segfault. Can you explain why and how to improve?

Thanks!

/KNEBB

CodePudding user response:

The json_object_put function is used to decrement the reference count of a json object, and free the memory associated with it if the reference count reaches zero. The segfault you're encountering is likely caused by attempting to free an object that has already been freed.

In the code you've provided, you're calling json_object_put twice, once on jsontmp and once on jsonmain. After the first call, both jsontmp and jsonmain will have their reference count decremented, and if they were the last references to those objects, they will be freed. If you then attempt to use either of those pointers again (by calling json_object_put a second time), you will be accessing memory that has been freed, which will cause a segfault.

To fix this issue, you should only call json_object_put on one of the objects (either jsontmp or jsonmain), as the other object will be freed when the first one is.

Also, you are using json_object_to_json_string_ext, which returns a constant char*, so you don't need to copy it into a new buffer (string = malloc(strlen(conststring) 1); and strcpy(string,conststring); are unnecessary) and you can directly return conststring.

You can do it like this:

const char *conststring = json_object_to_json_string_ext(jsonmain, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY);
json_object_put(jsonmain);
return (char*)conststring;

CodePudding user response:

From https://json-c.github.io/json-c/json-c-0.10/doc/html/json__object_8h.html#a04448b1c63173e1bfe49965835732075 :

void json_object_object_add     (   struct json_object *    obj,
        const char *    key,
        struct json_object *    val  
    )   

Upon calling this, the ownership of val transfers to obj. [..]

and

void json_object_put    (   struct json_object *    obj      )      

Decrement the reference count of json_object and free if it reaches zero. You must have ownership of obj prior to doing this or you will cause an imbalance in the reference count.

You do not have ownership in jsontmp, so doing json_object_put(jsontmp); is invalid. Just only call json_object_put(jsonmain);, jsonmain has ownership of jsontmp.

  • Related