我的程序有一个回调函数,调用它来处理以对象形式接收的通知。因为我们可以处理数百秒,所以这个回调函数通过生成一个单独的线程来处理事件来处理事件。这是回调函数:
void _OnEvent(LPCTSTR eventID, CNotification cNotificaton) {
if (_pActiveDoc) {
Param_Event* p = new Param_Event;
p->pDoc = _pActiveDoc;
p->lpszEventID = eventID;
p->cNotification = cNotification;
AfxBeginThread(ProcessEvent,p);
}
}
我的查询来自传递给回调方法的事实最初是在堆栈上创建的,因此(根据我的理解)仅限于调用方法的范围:
void CallingMethod(CString strEventID) {
CNotification cNotification;
// Fill in the details of the notification
_OnEvent(strEventID,cNotification);
}
CNotification
有一个完整的拷贝构造函数,并且由于Param_Event对象是在堆上创建的,我的信念是这会让原始CNotification
对象安全地超出范围,产生了线程从自己的私人"私人"在使用CNotification
删除Param_Event对象之前存在的delete
对象。然而事实是,我们正在(罕见但偶尔)崩溃,我想知道我的信念是否可能不正确:产生的线程是否仍然以某种方式访问原始对象?如果是这种情况,这可以解释由于罕见的对象掉落在范围之外并被覆盖在内存中而导致的崩溃,从而产生了内存访问异常。
我可以做对吗?我使用的方法有什么问题吗?最初是否更安全地在堆上创建通知对象(这将意味着更改我们的许多代码),或者在堆上构建一个新对象以传递给生成的线程?
供参考,这是我的ProcessEvent()方法:
Param_TelephoneEvent *p = (Param_TelephoneEvent*)lParam;
p->pDoc->OnTelephoneEvent(p->lpszEventID,p->cNotification);
delete p;
return 0;
欢迎所有建议。提前谢谢!
修改:复制构造函数:
CNotification& CNotification::operator=(const CNotification &rhs)
{
m_eamspeMostRecentEvent = rhs.m_eamspeMostRecentEvent;
m_eamtcsCallStatusAtEvent = rhs.m_eamtcsCallStatusAtEvent;
m_bInbound = rhs.m_bInbound;
strcpy(m_tcExtension , rhs.m_tcExtension);
strcpy(m_tcNumber, rhs.m_tcNumber);
strcpy(m_tcName,rhs.m_tcName);
strcpy(m_tcDDI,rhs.m_tcDDI);
strcpy(m_tcCallID,rhs.m_tcCallID);
strcpy(m_tcInterTelEvent,rhs.m_tcInterTelEvent);
m_dTimestamp = rhs.m_dTimestamp;
m_dStartTime = rhs.m_dStartTime;
m_nCallID = rhs.m_nCallID;
return *this;
}