MFC multi-threaded memory leak problem & workaround

Source: Internet
Author: User

In the interface programming with Visual Studio (such as MFC), the foreground UI can be implemented through the message loop mechanism of MFC. and the data processing for the background. We may use multithreading to handle it.

So for most people (especially my rookie), a faster way is to choose MFC Multithreading: AfxBeginThread or CreateThread to build multithreading. When one or two threads are still available. When 3 or more than 3 threads appear, a memory leak is most likely to occur. The cause analysis is for example the following:

Multithreading Insecurity for CWinThread:

Because CWinThread calls _beginthreadex to initialize the C execution-time library. In the same way, assuming that the thread is forced to terminate (TerminateThread), the memory release of the C execution-time data that caused the partial and reference count to fail because TerminateThread is not going to pipe C execution-time library. The most typical feature is that static variable memory reclamation using an STL library will make an error, resulting in a false-positive exception when the process exits.
In addition, assuming that AfxBeginThread frequently recycles and allocates threads, it can also cause crashes if not strictly manipulated.

VC6, we should strictly control the use of STL library, avoid the coexistence of MFC Library and STL Library, otherwise, there will be a lot of problems.


Reason:

AfxBeginThread directly calls the CreateThread create thread instead of the Beginthreadex function recommended under C, and the two functions are different, mainly due to the historical legacy of the C execution library.

errno, _doserrno, Strtok, _wcstok, Strerror, _strerror, Tmpnam, Tmpfile, Asctime, _/C + + execution period library variables and functions with problems in multithreaded environments Wasctime, Gmtime, _ECVT and _FCVT.
to make a multithreaded C + + program execute correctly, you must create a data structure and use it with theeach of the threads of the C + + execution period library function is associated. When you call the C + + run-time library, these functions must knowLook at the data block of the calling thread so that it does not adversely affect other threads.

does the system know that the data block is allocated when a new thread is created? The answer is that it does not know. The system simply does not know that the application you are getting is written in C + + . It is also not known that the thread in which you invoke the function is inherently unsafe. The problem is that you have to do all the work correctly.

To create a new thread. Never invoke the operating system's CreateThread function . You must call the C + + execution period library function _beginthreadex.


< Span style= "Color:rgb (51,51,51); Font-family:helvetica,tahoma,arial,sans-serif; font-size:14px; Line-height:24px "> The following are some important points about _beginthreadex:
      each thread obtains its own tiddata memory structure allocated by the stack of the C + + execution period library. (Tiddata structure bit The address of the thread function passed to _beginthreadex is stored in the Tiddata memory block.

The parameters passed to the function are also stored in the data block.

_beginthreadex does call CreateThread internally, because this is how the operating system knows how to create a new thread The only way. ## #能够看出调用_beginthreadex时分配了额外的内存空间.

< Span style= "Color:rgb (51,51,51); Font-family:helvetica,tahoma,arial,sans-serif; font-size:14px; Line-height:24px ">    assumes that CreateThread is called instead of calling _beginthreadex of the c / c + + execution period library to create a new thread, What is going to happen. When a thread calls a c / c + + execution-time library function that requires a TIDDATA structure, the following conditions occur (most c / c + + The run-time library functions are thread-safe functions and do not require this structure.

First
First. A/C + + execution library function attempts to get the address of a thread's data block (by calling TlsGetValue).

Assume that the return
NULL as the address of the Tiddata block. The calling thread does not have a tiddata block associated with that address. At this point, the C/C + + run-time library function allocates a tiddata block to the calling thread in the field and initializes it. The Tiddata block (via TlsSetValue) is then associated with the line threads.
# # # #_beginthreadex相相应的推出函数是_endthreadex, this function will release the contents of Tiddata.
---------------------------
Suppose you use CreateThread to create threads. And you do not use the above mentioned in the special implementation of the library, but also will not fail. It is best to call _beginthreadex this API to create a thread if you must use those execution libraries, otherwise the TIDDATA data block cannot be undone, causing a memory leak.

You can take the _beginthreadex source to understand.

Extended reading:

About the difference between _beginthreadex and CreateThread


MFC multi-threaded memory leak problem &amp; workaround

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.