Home > Archive > VC STL > April 2005 > Memory Leakage each time cerr or cout is used by a new thread
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Memory Leakage each time cerr or cout is used by a new thread
|
|
| David Fahlander 2005-04-01, 8:59 am |
| I have discovered a bug in the STL support in Visual C++ .NET 2003.
Each time a thread is writing to std::cerr or std::cout, memory is allocated
that is not freed when the thread exits.
Evidence! Create a new Console Application with VS .NET 2003 (empty
project). Modify the project settings so that it uses multi threading (/MT or
/MTd). Then add a main.cpp file with the following lines. Compile and run.
Look in the task manager. It leaks real much!
#include <windows.h>
#include <iostream>
unsigned long WINAPI thread_routine(void *t)
{
std::cout ("Hello...\n");
return 0;
}
void main()
{
for (;;) {
HANDLE threadHdl = CreateThread(NULL, 0, thread_routine, NULL, 0, NULL);
WaitForSingleObject (threadHdl, INFINITE);
CloseHandle (threadHdl);
}
}
What I do, is that I create a thread that, when it runs, writes something to
std::cout. The main thread waits for the thread to exit before it closes the
thread handle. This is done in an infinite loop.
THE INTERESTING THING: Remove the std::cout line and you get no memory
leakage. Or, you could change the std::cout to printf() and there is no
memory leakage.
| |
| Tom Widmer 2005-04-01, 4:03 pm |
| David Fahlander wrote:
> I have discovered a bug in the STL support in Visual C++ .NET 2003.
> Each time a thread is writing to std::cerr or std::cout, memory is allocated
> that is not freed when the thread exits.
From MSDN's help for CreateThread:
"A thread that uses functions from the static C run-time libraries
should use the beginthread and endthread C run-time functions for thread
management rather than CreateThread and ExitThread. Failure to do so
results in small memory leaks when ExitThread is called. Note that this
is not a problem with the C run-time in a DLL."
Tom
| |
| David Fahlander 2005-04-01, 4:03 pm |
| "Tom Widmer" wrote:
> David Fahlander wrote:
>
> From MSDN's help for CreateThread:
>
> "A thread that uses functions from the static C run-time libraries
> should use the beginthread and endthread C run-time functions for thread
> management rather than CreateThread and ExitThread. Failure to do so
> results in small memory leaks when ExitThread is called. Note that this
> is not a problem with the C run-time in a DLL."
>
> Tom
Thanks! The leak disappeared just by calling _endthread (); before the
thread returns 0.
| |
| Doug Harrison [MVP] 2005-04-01, 4:03 pm |
| On Fri, 1 Apr 2005 06:01:04 -0800, David Fahlander wrote:
> Thanks! The leak disappeared just by calling _endthread (); before the
> thread returns 0.
So you're now calling _endthread from a thread you didn't create with
_beginthread? Even if it appears to work, I doubt it's supported. You
should start your thread with _beginthreadex and then you don't need to
call _endthreadex, because it's done automatically.
Note that _endthread automatically closes the thread handle, which makes it
and _beginthread useless. I say this because _endthread is called
automatically when a thread created by _beginthread returns, and although
_beginthread returns the thread handle to you, you can't use it for
anything. There's an inherent race condition with a quickly exiting thread,
and even if you make it to WaitForSingleObject, it's undefined for a handle
to be closed while you're waiting on it. To conduct an orderly program
shutdown, you need to ask your secondary threads to exit and wait for them
to do so before exiting main, and because _(begin|end)thread make this
difficult at best, they should never be used. Instead, always use
_(begin|end)threadex, which give you ownership of the thread handle.
--
Doug Harrison
Microsoft MVP - Visual C++
| |
| Stephen Howe 2005-04-01, 4:03 pm |
| > Note that _endthread automatically closes the thread handle, which makes
> it
> and _beginthread useless.
Does that mean that _beginthread() is of no use whatsoever?
Stephen Howe
| |
| Doug Harrison [MVP] 2005-04-01, 4:03 pm |
| On Fri, 1 Apr 2005 19:34:36 +0100, Stephen Howe wrote:
>
> Does that mean that _beginthread() is of no use whatsoever?
IMO, it does. The rest of my message laid out the basis for the IMO and
explained why I think _(begin|end)threadex should be used instead.
MFC's CWinThread suffers from a similar problem as _(begin|end)thread, but
there you have the option of starting the thread suspended, turning off the
auto-delete behavior, and resuming the thread. This gives you ownership of
the CWinThread object and the thread handle.
--
Doug Harrison
Microsoft MVP - Visual C++
|
|
|
|
|