从来不写技术文章,因为没办法描述清楚观点。我一直认为,无法向别人解释清楚为什么的原因,一定在于自己还不是彻底地理解。拿出来说,不异于害人害已。这两天弄一个mfc的小程序,出了点问题,google了下,也只有提问的没找到回答。
其实对于mfc,在其快老掉牙时,因为日常不怎么用,也始终是一知半解。就当下山来害回人吧。
现象:vs2005新建一个console的程序,并调用AfxSocketInit(),会有memory leak. leak 的出处是sockcore.cpp中的
#ifndef_AFXDLL
pThreadState->m_pmapSocketHandle =new CMapPtrToPtr;
pThreadState->m_pmapDeadSockets =new CMapPtrToPtr;
pThreadState->m_plistSocketNotifications = new CPtrList;
#endif
很明显这个问题只会在使用静态mfc库链接时才会发生。事实上这三块空间会在afxstate.cpp中的~AFX_MODULE_THREAD_STATE()中被删除,只是这个析构也没被调用。
本来这个析构应该是被appmodul.cpp中的_AfxTermAppState()函数调用,这个函数也是只有在静态链接mfc库时才会被调用,因为它只有在
#fndef _AFXDLL
char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER),atexit(&_AfxTermAppState));
#else
char _afxInitAppState = (char)(AfxInitialize(FALSE,_MFC_VER));
#endif
时才会在程序结束时调用。
出问题的就在_afxInitAppState,在console程序中它不会被调用,而在windows程序中才会被调用。应该在项目属性中哪里可以设置。_afxInitAppState应该是这个函数列表里的一项__xc_a ~__xc_z,他们是在进入_tmain()之前被调用的初始化函数表,但在mfc的source里无法找到它们的定义,是被extern进来的。
好,下面就是出问题的顺序,因为初始化列表__xc_a~__xc_z中没有_afxInitAppState,使得程序离开时_AfxTermAppState无法被调用,也就使AFX_MODULE_THREAD_STATE没被析构,所以三块内存没被析构。可能是微软认国在console程序下_afxInitAppState是不需要被调用的。
目前解决的方案是在序退出前加上
#fndef _AFXDLL
AfxTermLocalData(NULL, TRUE);
#endif
是不是有其它问题不得而知,因为,对mfc的一知半解