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.

Was it helpful?

Solution 2

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 :).

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top