locked
Memory leak caused by _beginthread / _beginthreadex RRS feed

  • Question

  • Dear Sir/Madam,

    Question 1:

    We are facing with a memory leak issue caused by _beginthread and _beginthreadex functions. I am sending this request to seek help (probably a hotfix for visual c++ 2008) .

    To reproduce this issue, please compile the following code with visual c++ 2008, and run it on a windows 7 machine. For each thread this is around 4k memory leak. Run the same EXE file on windows XP. There is no memory leak.

    To see the memory leak please watch the memory size in the Task Manager.

    Compile the same code with Visual C++ 2013, and run on Windows 7 machine. No memory leak.

    Based on the above observation, we believe there is an memory leak issue with Visual C++ 2008 compiler.

    We need urgent help on this issue.

    Question 2:

    We have experience another issue that we do not understand. We run a service program on windows 7. If root the computer, the service program will automatically started. Then the service program can run without memory leak.

    If manually stop the service and start it again, there are rapid memory leak. Can anyone help us figure out what is difference between the service automatically started and manually restarted? 

    Thank you so much,

    Shugang Kang

    ---- test code to reproduce this issue ---

    #include "stdafx.h"

    #include <Windows.h>

    #include <process.h>

    unsigned Counter;

    unsigned __stdcall SecondThreadFunc( void* pArguments )

    {

    printf( "In second thread...\n" );

    while ( Counter < 1000000 )

    Counter++;

    _endthreadex( 0 );

    return 0;

    }

    int test_a_thread()

    {

    HANDLE hThread;

    unsigned threadID;

    printf( "Creating second thread...\n" );

    // Create the second thread.

    hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );

    // Wait until second thread terminates. If you comment out the line

    // below, Counter will not be correct because the thread has not

    // terminated, and Counter most likely has not been incremented to

    // 1000000 yet.

    WaitForSingleObject( hThread, INFINITE );

    printf( "Counter should be 1000000; it is-> %d\n", Counter );

    // Destroy the thread object.

    CloseHandle( hThread );

    return 0;

    }

    int _tmain(int argc, _TCHAR* argv[])

    {

    for (int k=0; k<5; k++)

    {

    for (int i=0; i<10000; i++)

    {

    test_a_thread();

    printf("%d threads created.\n", i+1);

    Sleep(10);

    }

    Sleep(5000);

    }

    }

    Friday, November 8, 2013 6:28 PM

Answers

  • Hi,

    According to your description, please refer to this MSDN document, we can find it notes that _endthread automatically closes the thread handle. (This behavior differs from the Win32 ExitThread API.) Therefore, when you use _beginthread and _endthread, do not explicitly close the thread handle by calling the Win32 CloseHandle API.  

    So, the problem is resulted from your explicitly calling the CloseHandle.

    Hope this can help you.

    Best Wishes,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, November 11, 2013 6:30 AM

All replies

  • Does it happen if you do not call _endthreadex?

    • Proposed as answer by nednibz Sunday, October 30, 2016 12:15 PM
    • Unproposed as answer by nednibz Tuesday, November 1, 2016 2:57 PM
    Friday, November 8, 2013 7:41 PM
  • Hi,

    According to your description, please refer to this MSDN document, we can find it notes that _endthread automatically closes the thread handle. (This behavior differs from the Win32 ExitThread API.) Therefore, when you use _beginthread and _endthread, do not explicitly close the thread handle by calling the Win32 CloseHandle API.  

    So, the problem is resulted from your explicitly calling the CloseHandle.

    Hope this can help you.

    Best Wishes,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, November 11, 2013 6:30 AM
  • Hi,

    I have the same problem in those days with VS.NET 2012

    We use _beginthreadex, not _beginthread, so it needs call CloseHandle, refer to msdn document

    Anyone knows how to fix the memory leak, 4k?

    Saturday, October 29, 2016 3:17 PM
  • I just test it with VS2013 today, it still has the problem

    my windows 7 is 32 bit

    somebody said it's np with VS2010 in windows 7, 64 bit

    http://www.cplusplus.com/forum/windows/131842/

    Sunday, October 30, 2016 9:41 AM
  • It's clear that a call of _beginthreadex also requires a call of CloseHandle in order to free the thread handle. The advice of Viorel_ not to call _endthreadex is the right way to go IMO since the call is not needed and even has the potential to cause trouble. Think about it, how can the C runtime library free resources belonging to a thread as long as the thread actually is running? It's much better and safer to let it happen when the thread really ends.
    Sunday, October 30, 2016 12:27 PM
  • The documentation says that "_endthread and _endthreadex cause C++ destructors pending in the thread not to be called."

    So, calling these functions can leak objects that normally are destructed by exiting their scope. When you let the thread function to return, destructors will be called as usual. 

    -- pa


    • Edited by Pavel A Sunday, October 30, 2016 1:54 PM
    Sunday, October 30, 2016 1:53 PM
  • I did not call _endthreadex before, and it has memory leak

    refer msdn: Terminating a thread with a call to endthread or _endthreadex helps ensure proper recovery of resources allocated for the thread.

    My understanding is _endthreadex should be called to make sure resources is released

    Monday, October 31, 2016 12:54 PM
  • Unfortunately, I tested it with VS2010 in windows XP, 32 bit today, it still has the problem

    How to fix it?

    Monday, October 31, 2016 12:57 PM
  • I did not call _endthreadex before, and it has memory leak

    refer msdn: Terminating a thread with a call to endthread or _endthreadex helps ensure proper recovery of resources allocated for the thread.

    My understanding is _endthreadex should be called to make sure resources is released

    The CRT will call _endthreadex after the thread returns.

      From MSDN -

    You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine that's passed as a parameter.

    Monday, October 31, 2016 12:58 PM
  • The main question is how to fix the memory leak problem?

    I can not believe MS has the bug for years

    Tuesday, November 1, 2016 5:25 AM
  • I just test it with VS2013 today, it still has the problem

    my windows 7 is 32 bit

    That 's interesting.  The OP indicated that the problem did not manifest on Win7 with VS2013.

    Have you considered installing VS2015 Community (Update 3)?

    Tuesday, November 1, 2016 2:24 PM
  • Hi RLWA32,

    I have tested VS2010, VS2012, VS2013, VS2015

    windows XP (32 bit), windows 7 (32 bit), windows 10 (64 bit)

    All of them have the memory leak


    Wednesday, November 2, 2016 2:22 AM
  • Which code are you using that manifests the memory leak?  Is it the code above from the OP, or is it the code referenced at http://www.cplusplus.com/forum/windows/131842/?

    Exactly which memory statistic from Task Manager is being used to identify the leak( i.e., the column title)?

    Wednesday, November 2, 2016 11:15 AM
  • the code is like Shugang Kang wrote above

    the column title is Memory(private working set)

    Thursday, November 3, 2016 5:30 AM
  • I ran the OP's code on a Win7 system.  The executable was built with VS2015 Update 3.   When the code started running the Task Manager reported a Working Set of 1744K and a Private Working Set of 344K.  These figures increased slightly to 1836K and 404K, respectively, during the very early part of code execution and then remained constant until program termination.

    This doesn't look like a memory leak to me.

    Thursday, November 3, 2016 3:21 PM
  • Hi RLWA332,

    You are right. _beginthreadex has no memory leak

    And I found the memory leak reason

    I use a third part dll, and it affects _beginthreadex memory leak

    I don't know why

    Thursday, November 17, 2016 8:52 AM