将堆上的变量发送到另一个线程
Posted
技术标签:
【中文标题】将堆上的变量发送到另一个线程【英文标题】:Send a variable on the heap to another thread 【发布时间】:2012-03-31 17:26:07 【问题描述】:我在 C++ 中有一个奇怪的问题。布尔值的地址被“销毁”但没有被触及。我知道有更好的方法来完成我尝试做的事情,但我想知道我做错了什么。
我有一个主课;这个主类包含另一个类的向量。当创建此对象的新实例时,会出现一个奇怪的问题。
这就是我的代码的工作方式:
当调用“第二个”对象的构造函数时,将启动一个线程。该线程作为参数获取一个结构。这是结构:
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);
我测试了什么:
当构造函数运行和关闭时,我记录了 AutoThreadData 和 AutoThreadData->Destroy
的地址;当构造函数关闭时,AutoThreadData
地址等于AutoThreadData
。所以这里没有问题。
AutoThreadData->Destroy
的地址在构造函数关闭时被销毁。但这怎么会发生呢?布尔值在堆上,KeyPressData
结构 (AutoThreadData) 在堆上。
Destroy before: 00A85328
Destroy after: FEEEFEEE
有人能解释一下为什么会崩溃吗?
我知道我可以将指向我的类的指针发送到线程。但我想知道这里出了什么问题。这样我就可以从错误中吸取教训。
有人可以帮我解决这个问题吗?
【问题讨论】:
能否在代码示例中添加MultiBoxClient的定义?另外,能不能把构造MultiBoxClient()的代码加进去? 谢谢,我添加定义和它的构造方式。 【参考方案1】:我猜你对向量犯了一个错误,使用类指针,而不是类本身,像这样:
vector<class*> //instead of vector<class>
【讨论】:
你指的是什么类?我只看到bool
和int
的向量
他指出:“这个主类包含另一个类的向量。”这确实是我的问题。感谢每一位帮助我的人。
@user1201889 - 我看不出这个答案对你有什么帮助,因为在问题的代码中没有向量对象的访问(只获取向量的地址并分配它),所以很清楚,改变向量的类型不会有什么不同。因此,要么您没有发布代码的相关部分(比其他人如何猜测?),或者如果您这样做了,请告诉我您在问题代码中所做的更改,以使其根据此答案工作。 【参考方案2】:
0xFEEEFEEE
表示已释放内存。也就是说,您AutoThreadData
已被删除,并且它不在您处于无限循环中的工作线程上。所以,它必须是你的主线程,也可能是你没有显示的析构函数。
无论您在何处销毁/释放您的 KeyPressData
实例,请将其注释掉或在此处设置断点以找出它发生的位置。
【讨论】:
问题确实是在创建实例时调用了析构函数。但我没有调用它。我将主线程添加到帖子中。 @user1201889:基于堆栈的生命周期的全部意义在于,在作用域结束时会自动为您调用析构函数。 是的,但是当我在堆上创建对象时也会调用析构函数。 不要猜测 - 在析构函数中设置一个断点,一旦命中就检查调用堆栈,看看它是从哪里调用的。你不可能无缘无故地调用它。以上是关于将堆上的变量发送到另一个线程的主要内容,如果未能解决你的问题,请参考以下文章
将数据发送到另一个 ViewController 的 Swift 问题
我们如何在 UI 线程中创建处理程序以将数据发送到另一个线程
将结构从一个进程发送到另一个进程的最简单方法是啥? [关闭]