0

当我使用 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())崩溃时。Visual Studio 调试器显示“无法读取内存”。为. 问题是什么?成员变量和局部变量有什么区别?flags_ = defaultFlags[type];document.hGenericValue(Type type)_flags


编辑:我设置f为使用在这里定义的回调setResponseCallback 并被f称为使用 dispatchResponseCallbacks 这里定义的回调。

4

2 回答 2

2

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

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

就像是

class Test
{
    ...

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

然后做例如

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

注意object不要超出范围。

于 2014-05-13T13:13:41.860 回答
0

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

于 2014-05-13T14:10:27.080 回答