Rapidjson文档作为成员变量崩溃了该应用程序

时间:2014-05-13 12:52:35

标签: c++ rapidjson

当我使用rapidjson文档作为成员变量并执行此操作时:

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());
    }
};

当我在CTOR if (m_jsonDocument.Parse<0>("{ \"hello\" : \"world\" }").HasParseError()) flags_ = defaultFlags[type];的{​​{1}}行document.h上拨打GenericValue(Type type)个应用时崩溃。 Visual Studio调试器显示“无法读取内存”。为_flags。问题是什么?成员变量和局部变量之间有什么区别?


编辑:我使用f defined heresetResponseCallback设置为回调,并使用{{1}将f作为回调调用} defined here

2 个答案:

答案 0 :(得分:2)

问题是,最有可能的是,当调用成员函数指针f时,它在没有实际对象的情况下被调用,这意味着成员函数中的this指针无效。当您尝试访问成员变量时,这会导致undefined behavior,因为这些访问会隐式使用(无效)this指针。

有几种方法可以解决这个问题,最直接的方法是使用静态成员函数作为回调,并将对象的实例作为用户数据传递(大多数回调系统允许这样做)。然后静态成员函数可以使用用户数据对象指针来调用实际函数。

这样的东西
class Test
{
    ...

public:
    static void f_wrapper(Test* object)
    {
        object->f();
    }
};

然后做例如。

Test object;
set_callback(&Test::f_wrapper, &object);

请注意object不会超出范围。

答案 1 :(得分:0)

正如@JoachimPileborg所说,我应该如何称呼f();他详细解释的原因之一。感谢Joachim指导正确的方向。实际上我的问题比Joachim想象的更愚蠢:)。问题是,当我的HTTP请求响应回来时,我正在调用ff是一个回调函数)。但是,就我在堆栈中分配Test t;而言,内存被解除分配,而this在响应返回时无效。我知道,这真的很愚蠢:)。