TRINH.NGUYEN
TRINH.NGUYEN

Reputation: 29

json_object_object_add, segmentation fault

I am using libjosn-c as below and encounter a Segmentation fault error.

If I remove the line json_object_object_add(root, "Child", value);, no error occurs.

int main(int argc, char **argv)
{
    json_object *root = NULL, *value = NULL;

    root = json_object_new_string("My Object");
    value = json_object_new_string("My Child Object");
    json_object_object_add(root, "Child", value);
    printf("to string =%s\n", json_object_to_json_string(root));

    json_object_put(value);
    json_object_put(root);

    return 0;
}

I am not experienced in libjson-c. Thanks for your help!

Upvotes: 0

Views: 2288

Answers (4)

n0741337
n0741337

Reputation: 2514

The problem is in the json_type of root. Your program creates two instances of json_type_string, to which you attempt to add a key/value pair to the one called root. The json-c library should have probably detected the incorrect json_type of root and ignored the add request or something, but instead crashes on the call to json_object_object_add(root, "Child", value); (the crash can be replicated at least in v0.11 of json-c).

If instead, you wrote the program like:

int main(int argc, char **argv)
{
  json_object *root = NULL, *value = NULL;

  root = json_object_new_object();                    /* json_type_object */
  value = json_object_new_string("My Child Object");  /* json_type_string */
  json_object_object_add(root, "Child", value);
  printf("to string =%s\n", json_object_to_json_string(root));

  json_object_put(root);

  return 0;
}

it works and returns the output

to string ={ "Child": "My Child Object" }

You can use functions like json_object_get_type() to determine the json_type of a json_objectif you write a function which takes one as a parameter.

Upvotes: 0

Steven
Steven

Reputation: 1

Because json_object_put(root) frees all the objects it owns too. Since you added "value" to "root" when you did the put(root) it also did the put(value). By having your json_object_put(value), you freed the memory for value, and when you did the json_object_put(root) it also tried to free the memory for value, and since it was already freed, you caused a segmentation fault.

Upvotes: 0

TRINH.NGUYEN
TRINH.NGUYEN

Reputation: 29

Thank you for your reply!

As I understand your explanation, just remove the line json_object_put(value);

However, I don't understand why the line json_object_object_add(root, "Child", value); causes error.

Thank you for your help.

Upvotes: 0

If I were you, I'd read the documentation of a library before starting to use it.

As described here json_object_object_add(root, "Child", value) transfers the ownership of value to root. It means you are no longer responsible for json_object_puting it. When you json_object_put the root it json_object_puts the value for you.

When you json_object_put the value, it's reference counter drops to 0 and it's memory gets freed. When you json_object_put the root, it attempts to json_object_put the value and fails because the value no longer exists.

If you don't want the value to outlive the root, just remove the json_object_put(value) line.

If you want to use value after root gets freed, use:

json_object_object_add(root, "Child", json_object_get(value))

Upvotes: 0

Related Questions