当我使用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 here将setResponseCallback
设置为回调,并使用{{1}将f
作为回调调用} defined here。
答案 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请求响应回来时,我正在调用f
(f
是一个回调函数)。但是,就我在堆栈中分配Test t;
而言,内存被解除分配,而this
在响应返回时无效。我知道,这真的很愚蠢:)。