x64 ... VS2015 ...在函数内部我调用线程:
CString* arr = new CString("test");
CWinThread *pThread;
if(!(pThread->AfxBeginThread(ThreadProc, (LPVOID)arr))) {
delete arr;
}
对于Proc:
UINT ThreadProc(LPVOID pParam) {
CString* InputString = (CString*)pParam;
delete InputString;
return 0;
}
如果线程正常完成,它会清理正常但如果应用程序在线程运行时关闭则会导致内存泄漏。在VS2008下,调试没有检测到它在VS2015下的任何泄漏。从那以后MFC是否清理线程的方式有变化吗?
答案 0 :(得分:0)
PROC:
UINT ThreadProc(LPVOID pParam) {
CMainFrame* pMainFrm = (CMainFrame*)AfxGetApp()->m_pMainWnd;
while(!pMainFrm->m_threadcancelflag ){
}
return 0;
}
在标题中:
HANDLE hThread;
BOOL m_shutdownflag;
volatile BOOL m_threadcancelflag;
来源:
CWinThread *pThread;
if(!(pThread = AfxBeginThread(ThreadProc, (LPVOID)arr, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED))) {
delete arr;
}
else{
::DuplicateHandle(GetCurrentProcess(), pThread->m_hThread, GetCurrentProcess(), &hThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
pThread->ResumeThread();
}
覆盖WM_CLOSE:
void CMainFrame::OnClose() {
DWORD dwExitCode;
if(hThread){
::GetExitCodeThread(hThread, &dwExitCode);
if (dwExitCode == STILL_ACTIVE) {
if(!m_shutdownflag){
m_shutdownflag = TRUE;
if (AfxMessageBox(_T("Running Process. \n\nQuitting now may result in a loss of data and/or incomplete database tables.\n\nTo quit anyway click \"OK\"\nTo allow the process to complete normally click \"Cancel\"."), MB_ICONSTOP | MB_OKCANCEL) == IDCANCEL) {
m_shutdownflag = FALSE;
return;
}
else {
m_shutdownflag = TRUE;
}
}
m_threadcancelflag = TRUE;
Sleep(500);
PostMessage(WM_CLOSE);
}
else {
::CloseHandle(hThread);
}
}
CFrameWndEx::OnClose();
}
编辑:这是完整的解决方案......对于记录来说,这是一个糟糕的程序员,他没有预见到意外情况,并编写了一个程序,该程序不会自行清理并依赖操作系统来执行程序应该已经完成。良好的编程习惯包括添加错误和异常处理以及自我清理。垃圾收集是编程的基础,尽管当程序在理想情况下结束时很容易实现,但是当它没有时,它会涉及更多,但良好的编程习惯决定了你必须始终预见到意外情况。我希望这段代码可以帮助别人。无论程序如何结束,此代码都不会因持续的线程而泄漏内存。