Matt Schaller
February 24th, 2004, 07:52 PM
Hello,
Thanks for the new forum.
I thought I would put in a tip / warning that I have discovered and if anyone would like to comment on it, please do.
Recently I developed a program that allowed the user to select a file, and then a worker thread would do some processing to it. It was very simple, because it was my first MFC application and I was doing it more for learning MFC than being able to use the actual program.
While the worker thread processed the file, it periodically sent messages to a modal dialog box that had a progress control that reflected how much data had been processed by the worker thread. Also on the modal dialog box was a Cancel button that set a global variable to true that the worker thread checks at every iteration to see if it should end itself.
Here is a very slimmed down version of my thread:
typedef struct tagTHREADPARMS
{
CString pathname;
} THREADPARMS;
void CMyClass::SomeCallingFunction()
{
THREADPARMS *ptp = new THREADPARMS;
ptp->pathname = m_pathname; // m_pathname is in our class
AfxBeginThread( ThreadFunc, (LPVOID) ptp );
}
DWORD ThreadFunc(LPVOID lpParam)
{
THREADPARMS *ptp = (THREADPARMS*) lpParam;
CString pathname = ptp->pathname;
delete ptp;
//open file with the pathname
while( !file.eof() )
{
if( g_bStopThread )
{
// send ''thread canceled" msg to modal dialog box
AfxEndThread( 0 );
}
}
// send "thread finished" msg to modal dialog box
AfxEndThread( 0 );
}
If the thread runs its course, AfxEndThread( 0 ) is called and it finishes completely without any user intervention. The thread exits fine and the program (in debug mode) exits fine with no memory leaks.
However, if g_bStopThread is set to true, AfxEndThread( 0 ) is called, and the thread exits normally. However, when I close the program (when I am in debug mode) it shows a memory leak at a certain allocation number. When I use _CrtBreakAlloc to locate where the memory is being allocated, it points me to this line:
CString pathname = ptp->m_pathname;
This leak had me going quite crazy -- after all, it was a local variable, placed on the stack, and when the thread exits, everything on the stack should be removed... right? Apparently not. Unless AfxEndThread() is called at the very end of your function, local variables will not be automatically destroyed. Fortunately there was someone who was as interested in this problem as I was, and he was the one that ultimately had it figured out, and the fix to this problem is to just return 0; because that will take care of the removal of local variables.
I thought I would share this information with all of you...
Matt Schaller
matt@swfla.rr.com
Thanks for the new forum.
I thought I would put in a tip / warning that I have discovered and if anyone would like to comment on it, please do.
Recently I developed a program that allowed the user to select a file, and then a worker thread would do some processing to it. It was very simple, because it was my first MFC application and I was doing it more for learning MFC than being able to use the actual program.
While the worker thread processed the file, it periodically sent messages to a modal dialog box that had a progress control that reflected how much data had been processed by the worker thread. Also on the modal dialog box was a Cancel button that set a global variable to true that the worker thread checks at every iteration to see if it should end itself.
Here is a very slimmed down version of my thread:
typedef struct tagTHREADPARMS
{
CString pathname;
} THREADPARMS;
void CMyClass::SomeCallingFunction()
{
THREADPARMS *ptp = new THREADPARMS;
ptp->pathname = m_pathname; // m_pathname is in our class
AfxBeginThread( ThreadFunc, (LPVOID) ptp );
}
DWORD ThreadFunc(LPVOID lpParam)
{
THREADPARMS *ptp = (THREADPARMS*) lpParam;
CString pathname = ptp->pathname;
delete ptp;
//open file with the pathname
while( !file.eof() )
{
if( g_bStopThread )
{
// send ''thread canceled" msg to modal dialog box
AfxEndThread( 0 );
}
}
// send "thread finished" msg to modal dialog box
AfxEndThread( 0 );
}
If the thread runs its course, AfxEndThread( 0 ) is called and it finishes completely without any user intervention. The thread exits fine and the program (in debug mode) exits fine with no memory leaks.
However, if g_bStopThread is set to true, AfxEndThread( 0 ) is called, and the thread exits normally. However, when I close the program (when I am in debug mode) it shows a memory leak at a certain allocation number. When I use _CrtBreakAlloc to locate where the memory is being allocated, it points me to this line:
CString pathname = ptp->m_pathname;
This leak had me going quite crazy -- after all, it was a local variable, placed on the stack, and when the thread exits, everything on the stack should be removed... right? Apparently not. Unless AfxEndThread() is called at the very end of your function, local variables will not be automatically destroyed. Fortunately there was someone who was as interested in this problem as I was, and he was the one that ultimately had it figured out, and the fix to this problem is to just return 0; because that will take care of the removal of local variables.
I thought I would share this information with all of you...
Matt Schaller
matt@swfla.rr.com