wxWidgets第十六课wxTimer没有调用停止导致崩溃的问题分析

0 xc0000005:读取位置0 xfeeeff06时发生访问冲突

,,跟踪调用堆栈的具体情况,代码崩溃点指向IMPLEMENT_APP (CTestApp)

调用堆栈指向:

, wxEntry (int, wchar_t * *)未知

, wxEntry (struct HINSTANCE__ *, struct HINSTANCE__ *, char *, int)未知

祝辞. WinMain (HINSTANCE__ *实例句柄,HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow)行4 c + +

,,,,,,,, __tmainCRTStartup()行528 c


经验

如果只是根据这些信息,显然没有任何的实际意义,从而引出下文的重点:当出现程序崩溃的时候,需要从当前的堆栈信息,不断的从最新的函数调用往前进行回溯,指向. WinMain (HINSTANCE__ *实例句柄,HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow)行4 c + +这一句的指针式白色的,而在调用堆栈的列表上,还有其他的信息,尤其是最前面的×××的指针指向的内容:wxEvtHandler: SafelyProcessEvent(类wxEvent和)未知,经过不断的回溯,才知道是wxTimerImpl发生错误,明显的这是一个定时器,而在程序中确实使用了定时器,现在已经锁定了目标,分析问题就不会太难了。之前没有分析出问题,就是没有逐一分析调用堆栈,看不懂系统调用没有关系,关键是哪些用户的调用会触发系统的调用从而导致问题的出现


跟踪调用堆栈

,, wxEvtHandler: SafelyProcessEvent(类wxEvent和)未知

,, wxTimerImpl: SendEvent (void)未知

,, wxTimerWndProc (struct HWND__ *, unsigned int, unsigned int,长)未知


说明在定时器处理消息的时候出现了问题,此时关闭窗口,应该已经销毁了定时器的实例指针,这个时候定时器应该接收不到任何的消息,但是从调用堆栈来看,定时器内部还是继续在处理消息,导致了问题的出现


查看代码

,,声明:wxTimer * m_timer;

,,,,创建对象:m_timer=new wxTimer(这个,TIMER_ID);

,,,,启动定时器:m_timer→开始(10);


结论

这里就有一个问题了,没有停止定时器,但是就算没有停止,发生的最终原因又是为何?当然了,通过在关闭窗口之前,调用m_timer→停止(),停止定时器,解决了该问题


扩展

类WXDLLIMPEXP_BASE wxTimer:公共wxEvtHandler


类WXDLLIMPEXP_BASE wxEvtHandler:公共wxObject

,,,,,,,,,,,,,,,,,,、公共wxTrackable

从上面看到定时器的继承关系


wxWidgets第十六课wxTimer没有调用停止导致崩溃的问题分析