I was reading this question, and here the jsoncpp CharReaderBuilder::newCharReader()
function returns a pointer to a dynamically created CharReader
object, which can then be used to parse a JSON.
I understand in that question the OP should have freed the returned pointer once it was used, since it was created on the heap. But, I am confused about whether, if we never store the returned pointer since it is for 1-time-use only, and write something like this:
Json::Value root;
Json::CharReaderBuilder().newCharReader()->parse(serverResponse.response,
serverResponse.response serverResponse.size - 1, &root, &Json::String());
Will this still cause a memory leak? If so, then in this case, I am not storing the pointer, so I cannot really call free()
or delete
to free that location of memory since I need a reference for that.
I guess I could somehow wrap the entire thing around the C unique_ptr
thing, but I think this should not cause any memory leak. Am I correct?
Edit: From the comments, it seems this will still cause a memory leak. So, how should I delete this pointer since I currently have no reference to it? Am I forced to create a reference and store the pointer if I want to avoid a memory leak? Is there no other way?
CodePudding user response:
"The other way" is using smart pointers. Consider the following examples.
#include <iostream>
struct A {
int b;
A(int _b) :b(_b) { std::cout << "A created." << std::endl; }
~A() { std::cout << "A destroyed." << std::endl; }
};
void c(A *a) {
std::cout << a->b << std::endl;
}
int main() {
c(new A(42));
return 0;
}
Running this:
% ./a.out
A created.
42
That temporary object created is never cleaned up.
#include <iostream>
#include <memory>
struct A {
int b;
A(int _b) :b(_b) { std::cout << "A created." << std::endl; }
~A() { std::cout << "A destroyed." << std::endl; }
};
void c(std::unique_ptr<A> a) {
std::cout << a->b << std::endl;
}
int main() {
c(std::make_unique<A>(27));
return 0;
}
Here we've use a smart pointer (std::unique_ptr
), and we can see that the destructor is called and the temporary is cleaned up.
% ./a.out
A created.
27
A destroyed.
CodePudding user response:
Will this still cause a memory leak?
Yes. The returned pointer is pointing at a new
'ed object, so it must be delete
'd when you are done using the object.
Am I forced to create a reference and store the pointer if I want to avoid a memory leak?
Yes, eg:
CharReader *reader = Json::CharReaderBuilder().newCharReader();
reader->parse(...);
delete reader;
Which can be wrapped in std::unique_ptr
so you don't have to delete
it manually, eg:
std::unique_ptr<CharReader> reader(Json::CharReaderBuilder().newCharReader());
reader->parse(...);
Alternatively, for a one-time use, you can use operator->
directly on a temporary unique_ptr
instance, eg:
std::unique_ptr<CharReader>(Json::CharReaderBuilder().newCharReader())->parse(...);
Either way, consider using an alias to make the code a little more readable, eg:
using CharReader_ptr = std::unique_ptr<CharReader>;
...
CharReader_ptr reader(Json::CharReaderBuilder().newCharReader());
reader->parse(...);
...
CharReader_ptr(Json::CharReaderBuilder().newCharReader())->parse(...);