场景
调用wxTimer定时器功能的时候,如果关闭当前的窗口,会出现上述的问题:0xC0000005: 读取位置 0xFEEEFF06 时发生访问冲突
说明
跟踪调用堆栈的具体情况,代码崩溃点指向IMPLEMENT_APP(CTestApp)
调用堆栈指向:
wxEntry(int &,wchar_t * *) 未知
wxEntry(struct HINSTANCE__ *,struct HINSTANCE__ *,char *,int) 未知
> WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) 行 4 C++
__tmainCRTStartup() 行 528 C
经验
如果只是根据这些信息,显然没有任何的实际意义,从而引出下文的重点:当出现程序崩溃的时候,需要从当前的堆栈信息,不断的从最新的函数调用往前进行回溯,指向WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) 行 4 C++这一句的指针式白色的,而在调用堆栈的列表上,还有其他的信息,尤其是最前面的×××的指针指向的内容:wxEvtHandler::SafelyProcessEvent(class wxEvent &)未知,经过不断的回溯,才知道是wxTimerImpl发生错误,明显的这是一个定时器,而在程序中确实使用了定时器,现在已经锁定了目标,分析问题就不会太难了。之前没有分析出问题,就是没有逐一分析调用堆栈,看不懂系统调用没有关系,关键是哪些用户的调用会触发系统的调用从而导致问题的出现
跟踪调用堆栈
wxEvtHandler::SafelyProcessEvent(class wxEvent &)未知
wxTimerImpl::SendEvent(void)未知
wxTimerWndProc(struct HWND__ *,unsigned int,unsigned int,long)未知
说明在定时器处理消息的时候出现了问题,此时关闭窗口,应该已经销毁了定时器的实例指针,这个时候定时器应该接收不到任何的消息,但是从调用堆栈来看,定时器内部还是继续在处理消息,导致了问题的出现
查看代码
声明:wxTimer *m_timer;
创建对象:m_timer = new wxTimer(this, TIMER_ID);
启动定时器:m_timer->Start(10);
结论
这里就有一个问题了,没有停止定时器,但是就算没有停止,发生的最终原因又是为何?当然了,通过在关闭窗口之前,调用m_timer->Stop(),停止定时器,解决了该问题
扩展
class WXDLLIMPEXP_BASE wxTimer : public wxEvtHandler
class WXDLLIMPEXP_BASE wxEvtHandler : public wxObject
, public wxTrackable
从上面看到定时器的继承关系
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。