As @JoachimPileborg noted it should be important how I call f();
One of the reasons he explained in details. Thanks to Joachim for directing to the right direction. Actually my problem was more stupid than Joachim could think :). The problem was that I was calling f
when the response to my HTTP request is back (f
was a callback function). But as far as I allocated Test t;
in stack, therefore the memory was de-allocated and this
was invalid in the point when the response was back. I know, that is really stupid :).
Rapidjson document as a member variable crashes that application
Question
When I use rapidjson document as member variable and do this:
class Test
{
rapidjson::Document m_jsonDocument;
public:
void f()
{
// WORKS FINE
rapidjson::Document document;
if (document.Parse<0>("{ \"hello\" : \"world\" }").HasParseError())
printf("ERROR PARSING JSON\n");
else
printf("%s\n", document["hello"].GetString());
// BUT HERE THROWS, WHY?
if (m_jsonDocument.Parse<0>("{ \"hello\" : \"world\" }").HasParseError())
printf("ERROR PARSING JSON\n");
else
printf("%s\n", m_jsonDocument["hello"].GetString());
}
};
When I call if (m_jsonDocument.Parse<0>("{ \"hello\" : \"world\" }").HasParseError())
app crashes on line flags_ = defaultFlags[type];
in document.h
in CTOR GenericValue(Type type)
. Visual Studio debugger says "Unable to read memory." for _flags
. What is the problem? What is the difference between member variable and local variable?
EDIT: I set f
as a callback using setResponseCallback
defined here and f
is being called as a callback using dispatchResponseCallbacks
defined here.
Solution 2
OTHER TIPS
The problem is, most likely, that you when the member function pointer f
is called it's called without an actual object, meaning that the this
pointer in the member function is invalid. This leads to undefined behavior when you try to access member variables, as those accesses uses the (invalid) this
pointer implicitly.
There are a couple of ways to solve this, the most straightforward is to use a static member function as callback, and pass an instance of the object as user-data (most callback systems allow this). Then the static member function can use the user-data object pointer to call the real function.
Something like
class Test
{
...
public:
static void f_wrapper(Test* object)
{
object->f();
}
};
Then do e.g.
Test object;
set_callback(&Test::f_wrapper, &object);
Take care that object
doesn't go out of scope.