2014-12-04 121 views
-1

Visual Studio(我正在使用2010,但我試過在其他版本)告訴我我的內存泄漏在我的類的行執行IMPLEMENT_DYNCREATE宏。IMPLEMENT_DYNCREATE上的內存泄漏與抽象的CWinThread派生類

重現步驟。

創建一個基本的MFC對話框應用程序。 添加使用類嚮導從的CWinThread派生的類:

部首:

class CMyThread : public CWinThread 
{ 
    DECLARE_DYNCREATE(CMyThread) 

protected: 
    CMyThread();   // protected constructor used by dynamic creation 

public: 
    virtual BOOL InitInstance(); 
    virtual int ExitInstance(); 

protected: 
    DECLARE_MESSAGE_MAP() 
}; 

CPP:

#include "stdafx.h" 
#include "TestProject.h" 
#include "MyThread.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 

// CMyThread 

IMPLEMENT_DYNCREATE(CMyThread, CWinThread) 

CMyThread::CMyThread() 
{ 
} 

BOOL CMyThread::InitInstance() 
{ 
    // TODO: perform and per-thread initialization here 
    return TRUE; 
} 

int CMyThread::ExitInstance() 
{ 
    // TODO: perform any per-thread cleanup here 
    return CWinThread::ExitInstance(); 
} 

BEGIN_MESSAGE_MAP(CMyThread, CWinThread) 
END_MESSAGE_MAP() 


// CMyThread message handlers 

現在,添加一個抽象的CWinThread派生類的報頭:

class CThreadAbstract : public CWinThread 
{ 
public: 
    virtual BOOL InitInstance() = 0; 
    virtual int ExitInstance() = 0; 
}; 

並將您原來的CWinThread派生類更改爲deriv編輯從CThreadAbstract代替:

class CMyThread : public CThreadAbstract 
{ 
    DECLARE_DYNCREATE(CMyThread) 

protected: 
    CMyThread();   // protected constructor used by dynamic creation 

public: 
    virtual BOOL InitInstance(); 
    virtual int ExitInstance(); 

protected: 
    DECLARE_MESSAGE_MAP() 
}; 

現在,從對話框類(的OnInitDialog)實例化你的線程的實例,並關閉它:

CMyThread * pMyThread = (CMyThread *)AfxBeginThread(RUNTIME_CLASS(CMyThread),0,0,CREATE_SUSPENDED); 
if (pMyThread) 
{ 
    pMyThread->m_bAutoDelete = false; 
    pMyThread->ResumeThread(); 
} 

if (pMyThread) 
{ 
    pMyThread->PostThreadMessage(WM_QUIT, 0, 0); 
    pMyThread = NULL; 
} 

運行調試器中的應用,然後點擊確定按鈕(或點擊esc)關閉它。

Whalla!內存泄漏指向:

IMPLEMENT_DYNCREATE(CMyThread, CWinThread) 

很顯然,我不是真正知道究竟發生了什麼事在這裏與IMPLEMENT_DYNCREATE導致此。我已經閱讀了MSDN文檔,看到它說宏將實例化類的一個實例,所以我猜測這是沒有正確清理的東西,但我不知道如何解決它。

+1

當您將m_bAutoDelete設置爲false時,您將負責刪除CMyThread對象。 – 2014-12-04 22:50:28

+0

@ ScottMcP-MVP所以你說的泄漏不是來自創建的第二個實例,而是來自原始實例?誰投下了這個問題,你是否介意告訴我這個問題有什麼不好的形式? – kinar 2014-12-05 01:24:25

+0

@ ScottMcP-MVP Nevermind my previous question。我刪除了設置autodelete標誌,泄漏消失,正如你所建議的。然後我去閱讀MSDN文檔,並確定它說的完全一樣。奇怪的是,我總是以這種方式使用CWinThread對象,並始終以相同的方式關閉線程,但從未碰到過這個(這就是爲什麼我認爲它與抽象類的使用有關)。我一直認爲autodelete標誌與線程終止而不是對象清理(oops)有關。如果你想把它作爲答案發布,我會接受它。 – kinar 2014-12-05 01:50:57

回答

1

當您將m_bAutoDelete設置爲false時,您將負責刪除CMyThread對象。