使用此关键字在结构中引用类时遇到问题

时间:2012-11-22 05:27:34

标签: c++ winapi pointers struct

标题文件:

// 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);
}

我在这里遇到一个简单的问题,我无法指责。

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

我的错误在哪里?

1 个答案:

答案 0 :(得分: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作为线程数据。在你的情况下,你只是通过结构传递*,所以只需将其作为参数传递

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);
}

在你的线程proc:

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

   etc...
}

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