请问:当线程被强行结束时如何释放堆上new的内存?
通过dll的一个导出函数中创建了线程,在该线程的InitInstance初始化部分通过new分配了大量的C++对象以及Windows资源窗口等等。如果该函数正常调用,并且线程正常结束时在ExitInstance中通过delete以及DestroyWindow等等释放资源。
如果该函数已经被调用,可是线程还在执行中时,当用户非正常结束主程序,线程将被强行结束,主程序将终止,Dll最终会被释放。此时无法进入线程的ExitInstance中来释放资源,在VC的Debug窗口中提示内存泄露。由于该函数可以被多次调用,可能产生多个线程,多次调用将进一步加大了内存泄漏。
由于使用的是regular dll,无论如何在Dll被释放时会调用CWinApp::ExitInstance,我计划通过每次在函数中创建线程时,将所创建的对象以及窗口资源的句柄通过vector保存在theApp的内部,当线程正常结束时修改theApp的vector[i]为NULL,当整个Dll卸载时,判断相应的值,如果不为NULL就执行释放工作。在往vector注册时我通过CCriticalSection保证一致。
可是发现,在异常退出清理资源时,无法成功delete掉new出的东西,而且DestroyWindow也不能奏效,引发了ASSERT失败。通过检测发现:在调用CWinApp::ExitInstance之前,所有创建的线程均已经终止。
请问:
1 以上情况下,为什么无法delete掉堆上new出的东西?是通过同一个指针值访问的。窗口句柄也无效。
2 有没有办法监控线程,在异常终止之前能够保证释放资源。
谢谢
[解决办法]
MFC规则DLL中的CWinApp对象是一个全局变量,在卸载DLL的时候调用ExitInstance,不是每个线程结束都调用的。
线程中可以用try来捕获异常,释放资源。
[解决办法]
如果线程被强行终止,调用堆栈中所有函数中new的堆内存(对象)都没有机会释放了。
如果有可能还是要让线程通过event得到事件,自己终止
[解决办法]