Archived

This topic is now archived and is closed to further replies.

CreateThread() and memory leaks

This topic is 5652 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am reading Windows 98 Programming from the Ground Up which is cautioning me to avoid using CreateThread() ExitThread() with the standard C libray. Instead I must use _beginthreadex() and _endthreadex(). Apparently not doing so on Visual C++ results in a small memory leak. The book I am reading is obviously a bit dated and I am wondering whether this is still an issue. I want to avoid using platform specific code as much as possible.

Share this post


Link to post
Share on other sites
The CRT thread functions allocate and deallocate per-thread storage. Some CRT functions return pointers to static data (strtok, for instance) and every thread needs its own set of that data. Thus the need for _beginthreadex and _endthreadex. If you are using CRT functions in your threads, you should start them with _beginthreadex; otherwise, feel free to use CreateThread.

Share this post


Link to post
Share on other sites
CRT stands for C Run-Time [library]. Open, for example, the docs on strtok.
quote:
strtok
Warning Each of these functions uses a static variable for parsing the string into tokens.


Basically, a function stores a static pointer to the string it tokenizes:

char *strtok (char *strToken, ...) {
static char *str = ...;
}

If strToken is non-NULL, static str is updated to be point to strToken, and the function tokenizes a new string. Otherwise, if strToken is NULL, the function uses the static str to access the string passed to it in one of the previous calls.
quote:

If multiple or simultaneous calls are made to the same function, a high potential for data corruption and inaccurate results exists.


This is because strtok can only handle one string at a time. Once static str is overwritten, there is no way to operate on that string.
quote:

Therefore, do not attempt to call the same function simultaneously for different strings and be aware of calling one of these function from within a loop where another routine may be called that uses the same function.


This is a logical result.
quote:

However, calling this function simultaneously from multiple threads does not have undesirable effects.


How so? Well, strtok doesn''t just have a static str pointer as I wrote. It actually obtains that pointer from what is called Thread Local Storage (TLS), which is a certain area of memory that can be set and read on a per-thread basis. For more information, see TlsAlloc, TlsGetValue, TlsSetValue. Each thread has its own block of memory that contains among other things all static function pointers required by the C run-time library functions.

This per-thread block must be allocated and freed, and that is accomplished by _beginthreadex and _endthreadex. If you are not using any CRT functions, you can ignore these and use CreateThread instead. However, to be on the safe side, if you are using CRT, you should begin and end thread with CRT functions. Otherwise, you may experience very strange bugs.

Was this better?

Share this post


Link to post
Share on other sites
Yeah I understand it now.

If I use CreateThread() a CRT function called by one thread could change the static data being used by a CRT function in another thread, But with __beginthreadex() the CRT functions would each have their own data.

CreateThread()+ CRT = potential for CRT functions to overwrite each data in use by another thread causing weird error at random intervals

__beginthreadex() + CRT each thread gets its own CRT data and everthing works as expected



Share this post


Link to post
Share on other sites
Not exactly. Using CreateThread will not read to overwrites; rather, you may end up reading/writing garbage pointers, or CRT may detect that _beginthreadex wasn''t called and allocate memory manually, but it will never free it because you don''t call _endthreadex.

Share this post


Link to post
Share on other sites