另一个线程中的成员函数丢失其类指针

问题描述 投票:0回答:3

我目前正在开发一个包含计时器的 SDL_Project。 SDL_Timer 可以有一个回调函数,并且由于我的计时器位于一个类中,因此该回调函数是一个静态成员函数,我通过 void* 参数将“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中。由于对于其他任务来说这一切都工作正常,因此我假设我的复制构造函数和赋值运算符都可以。 如果我在回调中检查 me 的值,结果发现 me 本身仍然保留了除指针之外的所有值。

编辑2:

我发现问题了。我复制B对象时没有更新父指针。谢谢大家的帮助。

c++ multithreading callback
3个回答
0
投票

您提供的信息太少,无法确定地回答您。最有可能的是,在从另一个线程调用

b
之前,对象
callback
被销毁(可能是从创建它的线程中)。

class B
添加带有一些日志记录的析构函数。在
C::callback()
的开头添加一些日志记录,这会给你一个提示发生了什么。另外,向
A
添加一个虚拟析构函数,如果您有类似
A* a = new B(); delete a;
之类的东西,这一点至关重要。


0
投票

如果您无法通过手动代码审查来检测问题,请使用 valgrind memcheck/helgrind 来帮助您检测任何潜在的内存损坏问题。


0
投票

也许使您的类成为单例或使整个类静态,这样您就可以将成员函数作为常规函数指针传递。静态成员函数指针不需要通过对象指针调用。我知道这个问题已经很老了,以防万一有人偶然发现这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.