Hey guys, i'm new to rapidjson library, and i've read rapidjson's documentations carefully.
but still, I have a problem when using rapidjson.
the following is the demonstration code which cause problem.
#include <iostream>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include <vector>
using namespace std;
using namespace rapidjson;
// just for debug
string rapidjsonValueToString(const Value& value) {
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
value.Accept(writer);
string str(buffer.GetString(), buffer.GetLength());
return str;
}
// parse
Document parse(const string& str, MemoryPoolAllocator<>& ma) {
Document doc(&ma);
doc.Parse(str.c_str(), str.size());
return doc;
}
int main() {
string string1("{\"k1\":\"v1\"}");
string string2("{\"k2\":\"v2\"}");
string string3("{\"k3\":\"v3\"}");
vector<string> vec{string1, string2, string3};
Document doc;
for (const auto& str : vec) {
doc = parse(str, doc.GetAllocator()); // here will cause SIGSEGV error in the second loop
std::cerr << "doc : " << rapidjsonValueToString(doc) << std::endl;
}
std::cerr << "doc : " << rapidjsonValueToString(doc) << std::endl;
return 0;
}
My problems are:
doc = parse(str, doc.GetAllocator()); this snippet will cause segment fault error in the second time when str = string2, could you please tell me why?Thanks in advance!
I guess i've got to know the reason about the problem 2:
= from parse to doc, cause the doc to call the destructor Destroy()https://github.com/miloyip/rapidjson/blob/f05edc9296507a9864d99931e203631c2ffd8d4a/include/rapidjson/document.h#L2156doc has no memory allocator.doc = parse(str, doc.GetAllocator()); which will use the previous memory allocator will cause segment fault error.Before
for (const auto& str : vec) {
doc = parse(str, doc.GetAllocator()); // here will cause SIGSEGV error in the second loop
std::cerr << "doc : " << rapidjsonValueToString(doc) << std::endl;
}
After
for (const auto& str : vec) {
auto d = parse(str, doc.GetAllocator()); // save the parse result in d
Pointer().Get(d)->Swap(doc); // get the root of d, and then swap with doc
std::cerr << "doc : " << rapidjsonValueToString(doc) << std::endl;
}
Although this solve the problem, but i'm not sure whether this is recommended way?
Or does anyone have better solutions ?
Yes. You should not assign to the doc because it destroys the allocator in it.
But I am not sure why you need this. Why not just simply doc.Parse(json)?
@miloyip , Thanks for your reply.
Yes, You are right.
I just want to use the same document's memory allocator for parse multiple times, and avoid copy operations as possible.
Most helpful comment
Yes. You should not assign to the
docbecause it destroys the allocator in it.But I am not sure why you need this. Why not just simply
doc.Parse(json)?