1

头文件:

// Free function to use in thread
unsigned int __stdcall WorkerFunction(void *);

class MyClass {
    public:
        int temp;
        void StartThread();
}

typedef struct {
    MyClass * cls;
} DATA;

CPP类:

void MyClass::StartThread() {
    temp = 1234;
    DATA data = {this};

    HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, &data, 0, 0);

    // Commented out for now while I address the current problem
    //CloseHandle(hThread);
}

unsigned int __stdcall WorkerFunction(void * param0) {
    MessageBox(NULL, "WorkerFunction()", "Alert", MB_OK);
    DATA * data = (DATA *) param0;
    MyClass* cls0 = data->cls;

    // Crashes when reference to cls0 is attempted.
    char buf[5];
    snprintf(buf, 5, "%i", cls0 ->temp);
    MessageBox(NULL, buf, "Alert", MB_OK);
}

我在这里遇到了一个简单的问题,我无法解决。

  • 我有一个线程的参数,它传递一个包含一个类的结构。
  • 我实例化结构,this然后在线程启动时传递它
  • 我尝试在工作函数中取消引用(?)它。
  • 至此,一切编译OK。
  • 当我添加行以访问类中的某些内容时,应用程序崩溃。

我的错误在哪里?

4

1 回答 1

1

您正在传递一个本地堆栈变量,该变量在返回时超出范围StartThread()。因此,您正在引用不再属于您的堆栈空间。

void MyClass::StartThread() {
    temp = 1234;
    DATA data = {this}; // << LOCAL VARIABLE OUT OF SCOPE ON FUNCTION EXIT

    HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, &data, 0, 0);

    // Commented out for now while I address the current problem
    //CloseHandle(hThread);
}

动态分配数据,或者更好的是,使数据成为线程数据的成员并作为线程数据MyClass传递。this在您的情况下,您只是通过结构传递 *this,所以只需将其作为参数传递

void MyClass::StartThread() {
    temp = 1234;

    HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, this, 0, 0);

    // Commented out for now while I address the current problem
    //CloseHandle(hThread);
}

在你的线程过程中:

unsigned int __stdcall WorkerFunction(void * param0) {
    MessageBox(NULL, "WorkerFunction()", "Alert", MB_OK);
    MyClass* cls0 = static_cast<MyClass*>(param0);

   etc...
}

无论您传递给线程过程,它都必须在所需的持续时间内具有有效的生命周期。由线程。要么确保通过将动态分配的所有权传递给线程,让它执行删除,要么传递一个已知的指针,在线程过程中的使用生命周期内保持确定状态。它似乎this满足了后者,所以你应该很高兴。

于 2012-11-22T05:32:48.033 回答