将堆上的变量发送到另一个线程

Send a variable on the heap to another thread

本文关键字:另一个 线程 变量      更新时间:2023-10-16

我在C++中遇到了一个奇怪的问题。布尔值的地址会被"销毁",但不会被触碰。我知道有更好的方法来完成我想做的事情,但我想知道我做错了什么。

我有一个主要的班级;这个主类包含另一个类的向量。当为这个对象创建一个新实例时,会出现一个奇怪的问题。

我的代码就是这样工作的:

当调用"2nd"对象的构造函数时,将启动一个线程。此线程获取一个结构作为参数。这是结构体:

struct KeyPressData
{
    vector<bool> *AutoPressStatus;
    vector<int> *AutoPressTime;
    bool * Destroy;
    bool * Ready;
};

结构在构造函数中填充:

MultiBoxClient::MultiBoxClient()
{
    //init data
    DestroyThread = new bool;
    ReadyThread = new bool;
    AutoThreadData = new KeyPressData;  
    //Reseting data
    *DestroyThread = false;
    *ReadyThread = false;   
    //KeyPressData configurating
    AutoThreadData->AutoPressStatus = &AutoPressStatus;
    AutoThreadData->AutoPressTime = &AutoPressTime;
    AutoThreadData->Destroy = DestroyThread;
    AutoThreadData->Ready = ReadyThread;
    //Start the keypress thread
    CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)AutoKeyThread,AutoThreadData,NULL,NULL); 
}

这是MultiBoxClient的防御:

class MultiBoxClient
{
    private:
        HWND ClientHandle;                                  
        vector<bool> KeyPresses;                                
        vector<bool> AutoPressStatus;                           
        vector<int> AutoPressTime;                              
        KeyPressData * AutoThreadData;                          
        bool * DestroyThread;                                       
        bool * ReadyThread;                                     
    public:
        MultiBoxClient();
        MultiBoxClient(HWND Handle);                            
        ~MultiBoxClient();                                      
        void EditClient(HWND Handle);                           
        void SendKeypress(vector<bool> KeyStatus);              
        void SendKeyCombination(unsigned int id);               
        void AutoCast(int Key,unsigned int Time,bool status);   
        bool IsAlive();                                         
};

MultiBoxClient是这样创建的:

int main()
{
    MultiboxControler * MainControler = new MultiboxControler;
    while(true)
    {
        Sleep(1000);
    }
    delete MainControler;
    return false;
}

只要构造函数在运行,程序就会正常运行。但是当构造函数关闭时,AutoThreadData->Destroy的地址就会被破坏。当我调用指针的值时,程序将崩溃。

void WINAPI AutoKeyThread(void * ThreadData)
{
    KeyPressData * AutoThreadData = (KeyPressData*)ThreadData;
    while(true)
    {   
        if(*AutoThreadData->Destroy == true)    //CRASH
        {
            *AutoThreadData->Ready = true;
            return;
        }
        Sleep(100);
    }
}

我测试了什么:

当constructor运行和关闭时,我记录了AutoThreadData和AutoThreadData->Destroy的地址;当构造函数关闭时CCD_ 3地址等于CCD_。所以这里没有问题。

AutoThreadData->Destroy的地址在构造函数关闭时被销毁。但这怎么可能发生呢?布尔值在堆上,KeyPressData结构(AutoThreadData)在堆上。

Destroy before: 00A85328
Destroy after: FEEEFEEE

有人能解释一下这次撞车的原因吗?

我知道我可以将指向类的指针发送到线程。但我想知道这里出了什么问题。这样我就能从错误中吸取教训。

有人能帮我解决这个问题吗?

我猜您在向量上犯了一个错误,请使用类指针,而不是类本身,如下所示:

vector<class*> //instead of vector<class>

0xFEEEFEEE表示已释放内存。也就是说,您的AutoThreadData已被删除,并且它不在处于无休止循环中的工作线程上。所以,它必须是你的主线程,也许是析构函数,而你没有展示。

无论您在哪里销毁/释放KeyPressData实例,都可以注释掉它,或者在那里设置一个断点来查找它发生的位置。