Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

memory leak #423

Closed
xverizex opened this issue Jun 12, 2018 · 6 comments
Closed

memory leak #423

xverizex opened this issue Jun 12, 2018 · 6 comments

Comments

@xverizex
Copy link

How to delete objects that were received by json_object_new_string? If you can not delete, will there be a memory leak or not?

@ploxiln
Copy link
Contributor

ploxiln commented Jun 12, 2018

json_object_new_string() returns a pointer to a new struct json_object. All json objects use reference-counting. If you call json_object_put() and it decrements the reference count of the object to zero, then the object will be freed. But usually you add this string object to another json object, and only call put() on the root object when you're done with the whole thing ...

http://json-c.github.io/json-c/json-c-0.13/doc/html/json__object_8h.html#a68c383f54544fca19b5f2425be397600

@hawicz hawicz closed this as completed Jun 13, 2018
@json-c json-c deleted a comment from yodapotatofly May 31, 2020
@andrewhodel
Copy link

https://stackoverflow.com/questions/14879994/how-to-free-json-object/63289941#63289941

Some good info on this there.

You have to understand how the library works.

json_tokener_parse() is first, and it creates an object that will act as a memory managing parent that all objects which are created from it use to access the data they define.

So if you get all the way down to making a char *str for a string field, that field doesn't actually store the string, the original object returned from json_tokener_parse() does.

This is the reason that you can't just use a normal free() and expect things to work as if it was a char array or something.

To be safe, don't use the json_tokener_parse_ex() function because you will have to also free the object that is the tokener, with json_tokener_parse() you don't need that argument.

Beyond that, to safely close everything just do:

while (json_object_put(orig_object) != 1) {
  // keep freeing
}

You should only need to do that once, but the library may change.

@hawicz
Copy link
Member

hawicz commented Aug 7, 2020

This has some terrible advice.

Avoiding json_tokener_parse_ex() because you don't want to free the tokener isn't "being safe", it's being lazy. (which could be perfectly fine, if you don't need the fine grained control that having a tokener object gives you)

Calling json_object_put in a loop implies that your program has completely lost track of what it has allocated and incremented reference counts for, and is a great way to end up using already freed memory, including calling json_object_put() on an object that is no longer valid.

@andrewhodel
Copy link

The tokener object has no options.

You didn't see that the loop is based on the put() return value.

Quit fighting, that's how you free the objects this library creates.

@hawicz
Copy link
Member

hawicz commented Aug 7, 2020

The tokener object does have operations that can be performed on it to either control parsing or obtain the results of parsing. Please see the functions at http://json-c.github.io/json-c/json-c-current-release/doc/html/json__tokener_8h.html for details.

Actually, I did see that your loop checks the return value, and I still maintain that calling it in that way is a bad idea. Though you might manage to cause the "orig_object" to be freed, calling json_object_put in a loop is dangerously sloppy and using such an approach in any non-trivial program will quite likely lead to use-after-free errors (and for simple programs it's entirely unnecessary to loop).

@andrewhodel
Copy link

andrewhodel commented Aug 7, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants