About the CWinThread object creation / deletion
-
Hello, do suppose I create a thread with the following:
CWinThread* m_pThread = AfxBeginThread ((AFX_THREADPROC) ThreadFunc, this,
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);and that I embed this in a class. Say in the methos "Start". Then... 1. If the class is instantiated onto the stack no problem whatsoever, otherwise 2. if the class is instantiated onto the heap I get memory leaks after destruction of the object. Question is the following: do I should delete explicitely the "m_pThread" object returned by AfxBeginThread after the thread ends ? Where do come from the thread related memory leaks I met ? Anyone has already encountered / solved this problem ? Cheers Federico
-
Hello, do suppose I create a thread with the following:
CWinThread* m_pThread = AfxBeginThread ((AFX_THREADPROC) ThreadFunc, this,
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);and that I embed this in a class. Say in the methos "Start". Then... 1. If the class is instantiated onto the stack no problem whatsoever, otherwise 2. if the class is instantiated onto the heap I get memory leaks after destruction of the object. Question is the following: do I should delete explicitely the "m_pThread" object returned by AfxBeginThread after the thread ends ? Where do come from the thread related memory leaks I met ? Anyone has already encountered / solved this problem ? Cheers Federico
If you have to explicitly delete the returned
m_pThread
depends on them_bAutoDelete
member of thatCWinThread
object: if the variable is set toTRUE
, the object automatically deletes itself when the thread execution terminates (I'm not very sure, but I remember that this is the default). -
If you have to explicitly delete the returned
m_pThread
depends on them_bAutoDelete
member of thatCWinThread
object: if the variable is set toTRUE
, the object automatically deletes itself when the thread execution terminates (I'm not very sure, but I remember that this is the default).I was thinking along the same lines, the fact is I got memory leaks when and only when I instantiate objects on the heap that start threads, the class interface is the following:
#ifndef CONSUMER_H
#define CONSUMER_H#include <afx.h>
#include <afxwin.h>
#include <set>
using namespace std;typedef set<CWnd*> ObserverListConsumerDef;
#include "ThreadMessages.h"
class CConsumer
{
public:
CConsumer(void);
virtual ~CConsumer(void);// Thread Interface
public:
bool Start(void); // Start the thread
bool Stop (void) { m_bStop = true; return true; } // Stop the thread
bool Abort(void); // Stop the thread (brute force kill it)
bool WaitForThread(DWORD dwWait); // Wait the thread to signal, i.e. to end
// dwWait in milliseconds or INFINITE
bool IsRunning() { return m_bIsRunning; }; // Is the thread running
bool IsSuccess() { return m_bSuccess; }; // Was the run successful ?
virtual bool Execute() = 0; // Override to provide functionality// the thread itself
protected:
static UINT ThreadFunc(LPVOID pVoid)
{
return( ((CConsumer*) pVoid)->LocalThreadFunc() );
}UINT LocalThreadFunc(void);
bool m_bIsRunning;
bool m_bSuccess;
bool m_bStop;
CWinThread* m_pThread;
HANDLE m_hThread;// Observer Windows
public:
void SetObserver(CWnd *pWnd);
void DelObserver(CWnd *pWnd);protected:
ObserverListConsumerDef m_ObserverList;
void SendMessageToObs(UINT nMsg, WPARAM wP, LPARAM lP);
};#endif // ! defined (CONSUMER_H)
-
I was thinking along the same lines, the fact is I got memory leaks when and only when I instantiate objects on the heap that start threads, the class interface is the following:
#ifndef CONSUMER_H
#define CONSUMER_H#include <afx.h>
#include <afxwin.h>
#include <set>
using namespace std;typedef set<CWnd*> ObserverListConsumerDef;
#include "ThreadMessages.h"
class CConsumer
{
public:
CConsumer(void);
virtual ~CConsumer(void);// Thread Interface
public:
bool Start(void); // Start the thread
bool Stop (void) { m_bStop = true; return true; } // Stop the thread
bool Abort(void); // Stop the thread (brute force kill it)
bool WaitForThread(DWORD dwWait); // Wait the thread to signal, i.e. to end
// dwWait in milliseconds or INFINITE
bool IsRunning() { return m_bIsRunning; }; // Is the thread running
bool IsSuccess() { return m_bSuccess; }; // Was the run successful ?
virtual bool Execute() = 0; // Override to provide functionality// the thread itself
protected:
static UINT ThreadFunc(LPVOID pVoid)
{
return( ((CConsumer*) pVoid)->LocalThreadFunc() );
}UINT LocalThreadFunc(void);
bool m_bIsRunning;
bool m_bSuccess;
bool m_bStop;
CWinThread* m_pThread;
HANDLE m_hThread;// Observer Windows
public:
void SetObserver(CWnd *pWnd);
void DelObserver(CWnd *pWnd);protected:
ObserverListConsumerDef m_ObserverList;
void SendMessageToObs(UINT nMsg, WPARAM wP, LPARAM lP);
};#endif // ! defined (CONSUMER_H)
When the thread ends, the
CWinThread
could be automatically deleted (depending on itsm_bAutoDelete
member), but the object ofCConsumer
class that you have dinamically allocated, should be deleted; you can explicitly test for the thread termination and delete the object, or make it auto-delete.-
explicitly delete the object:
CConsumer pConsumer = new CConsumer;
...
// Somewhere in your code, periodically do this:
if (!pConsumer->IsRunning())
delete pConsumer; -
add auto-delete feature to
CConsumer
:class CConsumer
{
...protected:
static UINT ThreadFunc(LPVOID pVoid)
{
CConsumer* pConsumer = (CConsumer*)pVoid;
UINT retVal = pConsumer->LocalThreadFunc();
if (pConsumer->m_bAutoDelete)
delete pConsumer;
return retVal;
}BOOL m_bAutoDelete;
...
};
-
-
When the thread ends, the
CWinThread
could be automatically deleted (depending on itsm_bAutoDelete
member), but the object ofCConsumer
class that you have dinamically allocated, should be deleted; you can explicitly test for the thread termination and delete the object, or make it auto-delete.-
explicitly delete the object:
CConsumer pConsumer = new CConsumer;
...
// Somewhere in your code, periodically do this:
if (!pConsumer->IsRunning())
delete pConsumer; -
add auto-delete feature to
CConsumer
:class CConsumer
{
...protected:
static UINT ThreadFunc(LPVOID pVoid)
{
CConsumer* pConsumer = (CConsumer*)pVoid;
UINT retVal = pConsumer->LocalThreadFunc();
if (pConsumer->m_bAutoDelete)
delete pConsumer;
return retVal;
}BOOL m_bAutoDelete;
...
};
Thanks, but I'm already deleting CConsumer objects from the heap when the thread ends. The point is still I've got some memory leaks related to the threads... i.e. <strcore> stuff. I cannot understand these leaks, as I memory manage the CConsumer objects in a proper way ! Cheers
-
-
Thanks, but I'm already deleting CConsumer objects from the heap when the thread ends. The point is still I've got some memory leaks related to the threads... i.e. <strcore> stuff. I cannot understand these leaks, as I memory manage the CConsumer objects in a proper way ! Cheers
Unfortunately, memory leaks are one of the hardest problems to investigate and the support given by Visual C++ to identify and fix them is not so good. Personally, I had a try to Bounds Checker (you can get a trial version from here[^]) and I think that it's a great product: when you start a debug session, it instruments all of your executables (exe, dll, etc.) and keep trace of almost everything (memory allocations, handles, GDI resources, etc.). Finally, when you close the application it gives you a report with all the found issues: for example for each memory leak it give you a lot of informations, and it's able to point out the line in your source code where the memory was been allocated. Hope this could help... Cheers