我目前正在开发包含计时器的SDL_Project。 SDL_Timer可以有一个回调函数,由于我的计时器位于一个类中,这个回调函数是一个静态成员函数,我通过void * -argument传递“this”。
但是该类还有另一个成员变量,它是一个指针。但是一旦我调用回调函数,这些指针就不再有效了。我认为哪种有意义,因为静态函数在另一个线程中被调用。
有没有办法解决这个问题?我对多线程不太熟悉,所以我不知道该寻找什么。
这是我正在做的事情的基本表示,尽管这个例子很好用,因为如果我的理论是正确的话,它就在一个线程中。
//A is just an interface so that B can hold a pointer to it
class A
{
public:
virtual int get() = 0;
};
class C
{
public:
C(){};
C(A* parent_arg)
{
parent = parent_arg;
}
void (*fptr)(C* sender) = nullptr;
static void callback(void* param)
{
//In my actual program, me has lost its parent pointer
C* me = (C*)param;
me->fptr(me);
};
//In my actual code, this function is from a SDL_Timer and
//runs in another thread
void Go()
{
callback(this);
}
A* parent = nullptr;
};
class B : A
{
public:
B()
{
c.parent = this;
};
virtual int get() { return myint; };
C c;
private:
int myint = 5;
};
void myfun (C* sender)
{
std::cout << sender->parent->get() << "\n";
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
b.c.fptr = myfun;
b.c.Go();
int test;
std::cin >> test;
return 0;
}
编辑:
以下是关于我在创建C和B后如何处理以及如何在实际程序中实现它们的更多信息。 所涉及的所有类都是可复制的。 B中的成员变量c位于boost :: stable_vector中。因为对于其他任务一切正常,我假设我的拷贝构造函数和赋值运算符都可以。 如果我在回调中检查我的值,结果发现除了指针之外,我自己仍然保留了它的所有值。
EDIT2:
我发现了问题。我复制B对象时没有更新父指针。谢谢大家的帮助。
答案 0 :(得分:0)
您提供的信息太少,无法肯定地回答您。在从另一个线程调用b
之前,对象callback
很可能被销毁(可能来自它创建的线程)。
将带有一些日志记录的析构函数添加到class B
。在C::callback()
的开头添加一些日志记录,这将为您提供一些提示。此外,向A
添加虚拟析构函数,如果您有类似A* a = new B(); delete a;
的内容,这一点至关重要。
答案 1 :(得分:0)
如果您无法通过手动代码检查发现问题,请使用valgrind memcheck / helgrind帮助您检测任何潜在的内存损坏问题。