I want to create a rapidjson::Value
from a JSON string, e.g., [1,2,3]
. Note: this is not a complete JSON object, it's just a JSON array. In Java I can use objectMapper.readTree("[1,2,3]")
to create a JsonNode
from a String.
My complete C++ code is as the following:
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <iostream>
// just for debug
static void print_json_value(const rapidjson::Value &value) {
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
value.Accept(writer);
std::cout << buffer.GetString() << std::endl;
}
//TODO: this function probably has a problem
static rapidjson::Value str_to_json(const char* json) {
rapidjson::Document document;
document.Parse(json);
return std::move(document.Move());
}
int main(int argc, char* argv[]) {
const char* json_text = "[1,2,3]";
// copy the code of str_to_json() here
rapidjson::Document document;
document.Parse(json_text);
print_json_value(document); // works
const rapidjson::Value json_value = str_to_json(json_text);
assert(json_value.IsArray());
print_json_value(json_value); // Assertion failed here
return 0;
}
Could anyone find out the problem in my function str_to_json()
?
PS: The code above works in GCC 5.1.0 but not in Visual Studio Community 2015.
UPDATE:
According to the suggestion of @Milo Yip, the correct code is as the following:
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <iostream>
static void print_json_value(const rapidjson::Value &value) {
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
value.Accept(writer);
std::cout << buffer.GetString() << std::endl;
}
static rapidjson::Document str_to_json(const char* json) {
rapidjson::Document document;
document.Parse(json);
return std::move(document);
}
int main(int argc, char* argv[]) {
const char* json_text = "[1,2,3]";
// copy the code of str_to_json() here
rapidjson::Document document;
document.Parse(json_text);
print_json_value(document); // works
const rapidjson::Document json_value = str_to_json(json_text);
assert(json_value.IsArray());
print_json_value(json_value); // Now works
return 0;
}
Simple answer: the return type should be rapidjson::Document
instead of rapidjson::Value
.
Longer version: A Document
contains an allocator to store all the values during parsing. When returning the Value
(actually the root of the tree), the local Document
object will be destructed and the buffers in the allocator will be released. It is like std::string s = ...; return s.c_str();
inside a function.