Discussion:
Memory leak reported using threads library
gast128
2004-11-22 22:21:03 UTC
Permalink
Dear all,

Downloading and using the 1.32 version was probably not such a good idea...

Now I get a mem-leak reported by the debug crt of VC 7.1. The report is
located in 'init_threadmon_mutex' where a global object is allocated but never
deleted. Before we start a discussion of what is a memory leak or not, in our
production code we do not accept any leak reported by VC. The past has learned
us that if you accept one leak, programmers/colleaques start to ignore them
and in the end you have 200 leaks, instead of this one.

I guess it wouldn't be difficult to resolve this one, on process exit it can
be deallocated. And yes I am aware of the (phoenix) singleton discussions in
Alexandrescu/Meyers, but really this kind of reinit of singletons after atexit
calls won't happen too much.

Wkr,
me
Cory Nelson
2004-11-22 22:41:38 UTC
Permalink
IIRC there was an intentional leak in the threads library that is
cleaned up on exit (the debug crt isn't perfect.. it can report global
std::strings as leaks also), maybe this is it?
Post by gast128
Dear all,
Downloading and using the 1.32 version was probably not such a good idea...
Now I get a mem-leak reported by the debug crt of VC 7.1. The report is
located in 'init_threadmon_mutex' where a global object is allocated but never
deleted. Before we start a discussion of what is a memory leak or not, in our
production code we do not accept any leak reported by VC. The past has learned
us that if you accept one leak, programmers/colleaques start to ignore them
and in the end you have 200 leaks, instead of this one.
I guess it wouldn't be difficult to resolve this one, on process exit it can
be deallocated. And yes I am aware of the (phoenix) singleton discussions in
Alexandrescu/Meyers, but really this kind of reinit of singletons after atexit
calls won't happen too much.
Wkr,
me
_______________________________________________
Boost-users mailing list
http://lists.boost.org/mailman/listinfo.cgi/boost-users
--
Cory Nelson
http://www.int64.org
gast128
2004-11-23 09:56:16 UTC
Permalink
Post by Cory Nelson
IIRC there was an intentional leak in the threads library that is
cleaned up on exit (the debug crt isn't perfect.. it can report global
std::strings as leaks also), maybe this is it?
Are you sure? I couldn't find the corresponding 'delete'. Setting a breakpoint
on 'on_process_exit', I gets fired, but this code dosen't clean it up either.

As far as the m$ debug crt concerns, the reporting is correct. However one has
to take great care in when the _CrtDumpMemoryLeaks function gets called. For
example MFC has a global object _AFX_DEBUG_STATE, which in its destructor
calls this function. The trick is then to postpone this call to the end, for
example by loading the mfc71d.dll as first (and then it gets unloaded as
last). Here in our production code global std::strings don't get reported.

Wkr,
me
Roland Schwarz
2004-11-22 23:21:03 UTC
Permalink
Post by gast128
Downloading and using the 1.32 version was probably not such a good idea...
Why do you think so? I am facing a similar situation in that I will need
to rewrite parts of my code
that is using ublas. Altough I think it is worth the effort. Remember:
boost (as I understand it) is not
intended as beeing API stable! I only expect parts beeing stable that
are already in the standard.
Others constantly face improvement. And this is the place where it is to
happen. Do I get something wrong?
Post by gast128
Now I get a mem-leak reported by the debug crt of VC 7.1. The report is
located in 'init_threadmon_mutex' where a global object is allocated but never
deleted. Before we start a discussion of what is a memory leak or not, in our
production code we do not accept any leak reported by VC. The past has learned
us that if you accept one leak, programmers/colleaques start to ignore them
and in the end you have 200 leaks, instead of this one.
Granted. However as I have found out using the MSVC memory leak
detection can be tricky at times.
One usually must be careful not to generate false alarms. Which
detection system do you use?
(Sidebar: wouldn't a boost::memory_debug lib be desirable?)
E.g. when inside MFC you cannot be sure when the detection code actually
triggers, since it is called
from within a destructor of a global object.
If you are also allocating dynamic memory from a global constructor the
leak is reported depending
on the order of constructor calls. (Don't know why MS deactivated the
CRT detection when using
MFC....)
Post by gast128
I guess it wouldn't be difficult to resolve this one, on process exit it can
be deallocated.
I guess you are refering to the (documented) leak in tss.cpp, aren't you?

// Intentional memory "leak"
// This is the only way to ensure the mutex in the global data
// structure is available when cleanup handlers are run, since the
// execution order of cleanup handlers is unspecified on any platform
// with regards to C++ destructor ordering rules.
tss_data = temp.release();

Getting rid of it however is not as trivial as it might seem at first
glance, since
the TLS code is able to clean up even when used from non boost::threads.
There is also a yet to be discussed issue what should happen when the main
thread exits but a user thread is still running. (When you have a look
at pthreads,
this is quite legal.) And what is "process exit" when speaking about
global ctors/dtors?
Post by gast128
And yes I am aware of the (phoenix) singleton discussions in
Alexandrescu/Meyers, but really this kind of reinit of singletons after atexit
calls won't happen too much.
Sorry I am not aware of this discussions, could you give me a short
overview?
I suspect the problem is similar to when using the CRT together with the
native CreateThread
API. In this case you are also introducing an unavoidable memory leak,
where the
CRT's TLS doesn't get deallocated. (Or occasionally will be reallocated.)

However I already have proposed a solution to the above problem (at
least for the windows version)
which is based on reference counting. This however requires a
(significant) bit of rewrite
which I think Michael Glassford did not want to introduce so short
before release.
At least the leak is intentional and well understood.

But I agree it _is_ ugly and it should be removed for any reason, no matter.

Roland
gast128
2004-11-23 11:04:55 UTC
Permalink
Post by Roland Schwarz
Post by gast128
Downloading and using the 1.32 version was probably not such a good idea...
Why do you think so? I am facing a similar situation in that I will need
to rewrite parts of my code
This was a joke: the c++ standard chose for stability and therefore ended up
in weird constructs. So I think boost follows the path in fixing/refactor
things, instead of sticking to (incorrect) old versions. This has my
preference too.
Post by Roland Schwarz
Granted. However as I have found out using the MSVC memory leak
detection can be tricky at times.
One usually must be careful not to generate false alarms. Which
detection system do you use?
(Sidebar: wouldn't a boost::memory_debug lib be desirable?)
E.g. when inside MFC you cannot be sure when the detection code actually
triggers, since it is called
from within a destructor of a global object.
If you are also allocating dynamic memory from a global constructor the
leak is reported depending
on the order of constructor calls. (Don't know why MS deactivated the
CRT detection when using
MFC....)
See my other response. I guess we both noticed the same, but this can be
circumvented by loading the mfc71d.dll as one of the first (e.g. after
ntdll.dll).
Post by Roland Schwarz
Post by gast128
I guess it wouldn't be difficult to resolve this one, on process exit it can
be deallocated.
I guess you are refering to the (documented) leak in tss.cpp, aren't you?
// Intentional memory "leak"
// This is the only way to ensure the mutex in the global data
// structure is available when cleanup handlers are run, since the
// execution order of cleanup handlers is unspecified on any platform
// with regards to C++ destructor ordering rules.
tss_data = temp.release();
Getting rid of it however is not as trivial as it might seem at first
glance, since
the TLS code is able to clean up even when used from non boost::threads.
There is also a yet to be discussed issue what should happen when the main
thread exits but a user thread is still running. (When you have a look
at pthreads,
this is quite legal.) And what is "process exit" when speaking about
global ctors/dtors?
Post by gast128
And yes I am aware of the (phoenix) singleton discussions in
Alexandrescu/Meyers, but really this kind of reinit of singletons after atexit
calls won't happen too much.
Sorry I am not aware of this discussions, could you give me a short
overview?
I suspect the problem is similar to when using the CRT together with the
native CreateThread
API. In this case you are also introducing an unavoidable memory leak,
where the
CRT's TLS doesn't get deallocated. (Or occasionally will be reallocated.)
Alexandrescu discusses in his book 'Modern C++ Design' singletons and the
problem of destroying it (chapter 6). There can be a problem if the singletons
are called again in exit code. While this can be a problem, I guess in
practice it will not happen often, or can be circumvented. The m-leak I
noticed is in tss_hooks.cpp, in fct 'init_threadmon_mutex'.
Post by Roland Schwarz
But I agree it _is_ ugly and it should be removed for any reason, no matter.
It would be nice. For the moment I will discourage the use of the thread
libraries because of this issue, although it is a nice library.

Wkr,
me
a***@ati-uk.com
2004-11-23 13:07:28 UTC
Permalink
I don't mind any one off small leaks. They may not be nice but no one is
going to notice them. What bothers me is when memory keeps leaking for each
iteration of the loop.

I don't bother with the microsoft crt leak stuff. It's rarely that much use
in complex projects and even if it does detect a leak it rarely can tell you
where it is. As it turns out the crt leak detect stuff doesn't seem to show
any leak (at least on my system), but lets say I put in my own my own leak
of say new char[10] or something then the leak messages pour out.

Use windows performance counters however and it's a different story, watch
the working set rocket up. And it seems to increase at different rates
depending on what the thread is doing. Eventually you will run out of memory
entirely. Use the crt dll in your main program however and the working set
is dead flat.
What I don't understand is your mentioning of the boost::function lib.
Where do you think it is getting used in
your example?
boost::function is being used in the constructor of thread i believe.

Has anyone been able to confirm this leak or is it just me?

Naturally boost::threads is a dll only (at least v 1.30 which i'm currently
using) and it itself can either link dynamically or statically to the crt.
It doesn't make any difference which though. I have to link dynamically to
crt in my program to avoid the leak. Why should this make a difference?

I don't particular want to upgrade to 1.32 for my project as it's rather
late in the day. I don't want any other issues creeping in and I've resolved
the issue by using the dll. However I thought I should report my findings
and see if anyone knows anything about it. Do we know if there is no leak in
1.32 or is it still there?

Thanks.

Alan
Ben Hutchings
2004-11-23 14:29:11 UTC
Permalink
Post by a***@ati-uk.com
I don't mind any one off small leaks. They may not be nice but no one is
going to notice them. What bothers me is when memory keeps leaking for each
iteration of the loop.
<snip>
Post by a***@ati-uk.com
Has anyone been able to confirm this leak or is it just me?
I think most people have learned from bitter experience to avoid trouble
by using the DLL configuration of the CRT.
Post by a***@ati-uk.com
Naturally boost::threads is a dll only (at least v 1.30 which i'm currently
using) and it itself can either link dynamically or statically to the crt.
It doesn't make any difference which though. I have to link dynamically to
crt in my program to avoid the leak. Why should this make a difference?
<snip>

Multithreaded configurations of MSVCRT allocates some per-thread memory
as needed, e.g. for the object that localtime returns a pointer to. To
ensure that this memory is freed at thread exit, you must either use a
DLL configuration of the CRT or ensure that all threads that call into
it are started using the _beginthread or _beginthreadex function. The
Boost.Thread DLL is not (and cannot be) linked to the same CRT that is
statically linked into your executable, so neither of these conditions
is satisfied.

If I remember correctly, any memory allocated in your executable cannot
be deallocated in the Boost.Thread DLL, or vice versa, since they have
separate heaps. I would expect an attempt to do so to result in a
crash, but it might in some cases be silently ignored, resulting in a leak.

Ben.
gast128
2004-11-23 15:42:23 UTC
Permalink
Post by a***@ati-uk.com
I don't mind any one off small leaks. They may not be nice but no one is
going to notice them. What bothers me is when memory keeps leaking for each
iteration of the loop.
I don't bother with the microsoft crt leak stuff. It's rarely that much use
in complex projects and even if it does detect a leak it rarely can tell you
where it is. As it turns out the crt leak detect stuff doesn't seem to show
any leak (at least on my system), but lets say I put in my own my own leak
of say new char[10] or something then the leak messages pour out.
Well I totally disagree.

I am working now on a project, which solution consists of 73 vc-projects (more
than 2500 files) and it does not leak memory in its main loop, thanks to the
debug crt of m$. We have overwritten the new and delete operator like m$ in
MFC does so we get accurate memory leak reporting. If you take this business
serious one can not allow any memory leak reported by the debug crt.

And of course if you use rare fct's like VirtualAlloc or GlobalAlloc, they are
not reported, but there is really no need to use them. Even the speed
advantage can be argued about.

Wkr,
me
John Maddock
2004-11-24 11:14:30 UTC
Permalink
Post by a***@ati-uk.com
Naturally boost::threads is a dll only (at least v 1.30 which i'm currently
using) and it itself can either link dynamically or statically to the crt.
It doesn't make any difference which though. I have to link dynamically to
crt in my program to avoid the leak. Why should this make a difference?
That's your problem: there must be one single rtl shared both by your code
and the Boost.Threads dll: and that means using the dynamic C runtime.
Frankly I'm surprised your code didn't just crash if you were mixing
runtimes :-(

John.
Roland Schwarz
2004-11-25 07:46:08 UTC
Permalink
Post by John Maddock
That's your problem: there must be one single rtl shared both by your
code and the Boost.Threads dll: and that means using the dynamic C
runtime.
That surprises me somewhat.
Explicitely:

mydll depending on dynamic CRT.

myapp depending on static CRT and depending on mydll.

You think this is not possible?
Just tried it. Found no obvious problem. Are there hidden traps?

If this would not be possible you never could write a self contained dll !
But I think I didn't understand your argument corectly, could you
elaborate please?

Hmm, when I rethink the issue the following might happen:
Writing a app that uses static CRT, then requesting for the DLL version
of a boost lib. Could it be that the autolink feature pulls in dll versions
of CRT? If this is the case this points out a problem with the autolink,
and has nothing to do with the unfeasability of the above scenario.

Roland
Peter Dimov
2004-11-25 11:42:46 UTC
Permalink
Post by Roland Schwarz
Post by John Maddock
That's your problem: there must be one single rtl shared both by your
code and the Boost.Threads dll: and that means using the dynamic C
runtime.
That surprises me somewhat.
mydll depending on dynamic CRT.
myapp depending on static CRT and depending on mydll.
You think this is not possible?
Just tried it. Found no obvious problem. Are there hidden traps?
It works as long as you don' allocate in one and delete in the other.
C-style interfaces are fine, but passing a std::string from the EXE to the
DLL (or vice versa) will fail. shared_ptr will work, though :-) unless you
unload the DLL that has created it, of course. Deleting an object with a
virtual destructor works, too.
Roland Schwarz
2004-11-25 12:08:29 UTC
Permalink
Post by Peter Dimov
It works as long as you don' allocate in one and delete in the other.
C-style interfaces are fine, but passing a std::string from the EXE to
the DLL (or vice versa) will fail. shared_ptr will work, though :-)
unless you unload the DLL that has created it, of course. Deleting an
object with a virtual destructor works, too.
That makes sense to me. A very convincing argument!
I would suggest to add this into the comment section of autolink.hpp:

#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK)
# define BOOST_LIB_PREFIX
#elif defined(BOOST_DYN_LINK)
# error "Mixing a dll boost library with a static runtime is a really
bad idea..."
#else
# define BOOST_LIB_PREFIX "lib"
#endif

I really did not figure out from the message why this was a "really bad
idea..."
(Since there is no obvious technical reason.)

BTW.: I would even prefer this being a warning, since as long as beeing
careful
there are usages where it could be of advantage.

Roland
Roland Schwarz
2004-11-25 10:45:23 UTC
Permalink
I inadvertently replied to the wrong posting.
Post by John Maddock
That's your problem: there must be one single rtl shared both by your
code and the Boost.Threads dll: and that means using the dynamic C
runtime.
That surprises me somewhat.
Explicitely:

mydll depending on dynamic CRT.

myapp depending on static CRT and depending on mydll.

You think this is not possible?
Just tried it. Found no obvious problem. Are there hidden traps?

If this would not be possible you never could write a self contained dll !
But I think I didn't understand your argument corectly, could you
elaborate please?

Hmm, when I rethink the issue the following might happen:
Writing a app that uses static CRT, then requesting for the DLL version
of a boost lib. Could it be that the autolink feature pulls in dll versions
of CRT? If this is the case this points out a problem with the autolink,
and has nothing to do with the unfeasability of the above scenario.

Roland
Richard Howells
2004-11-25 11:23:16 UTC
Permalink
There are traps in the MS world. Some CRT functions (think strtok - yuk)
use static data. If you build with the statically linked version of the
library, each executable (.exe AND .dll) has it's own copy of that static
data and they don't know about each other.

All executables built with the dynamically linked version share the same
copy of that static data.

If you use the dynamically linked version then you should (on Win NT and up
systems - not Win 9x) share the same copy of the code with all other apps in
the system that use the CRT.

HTH

- Richard

-----Original Message-----
From: boost-users-***@lists.boost.org
[mailto:boost-users-***@lists.boost.org] On Behalf Of Roland Schwarz
Sent: 25 November 2004 10:45
To: boost-***@lists.boost.org
Subject: Re: [Boost-users] Re: Memory leak reported using threads library

I inadvertently replied to the wrong posting.
Post by John Maddock
That's your problem: there must be one single rtl shared both by your
code and the Boost.Threads dll: and that means using the dynamic C
runtime.
That surprises me somewhat.
Explicitely:

mydll depending on dynamic CRT.

myapp depending on static CRT and depending on mydll.

You think this is not possible?
Just tried it. Found no obvious problem. Are there hidden traps?

If this would not be possible you never could write a self contained dll !
But I think I didn't understand your argument corectly, could you
elaborate please?

Hmm, when I rethink the issue the following might happen:
Writing a app that uses static CRT, then requesting for the DLL version
of a boost lib. Could it be that the autolink feature pulls in dll versions
of CRT? If this is the case this points out a problem with the autolink,
and has nothing to do with the unfeasability of the above scenario.

Roland




_______________________________________________
Boost-users mailing list
Boost-***@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.797 / Virus Database: 541 - Release Date: 15/11/2004


---
Outgoing mail is Virus checked.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.797 / Virus Database: 541 - Release Date: 15/11/2004
Roland Schwarz
2004-11-25 11:59:28 UTC
Permalink
Post by Richard Howells
There are traps in the MS world. Some CRT functions (think strtok - yuk)
use static data. If you build with the statically linked version of the
library, each executable (.exe AND .dll) has it's own copy of that static
data and they don't know about each other.
All executables built with the dynamically linked version share the same
copy of that static data.
If you use the dynamically linked version then you should (on Win NT and up
systems - not Win 9x) share the same copy of the code with all other apps in
the system that use the CRT.
I can understand this. But I cannot see why this will be a problem.
Case 1):
Singgle threaded: As long as one isn't calling functions that modify
this data in between
no harm is done, whether two instances of static data or not.
Case 2):
Multi threaded: Every thread has its own local copy of static data in
TLS storage.
No harm again.

But perhaps I am still simply not beeing able to see the trap?

BTW.: Having a separate copy of the data in the (boostified) DLL will
improve robustness, not
making it worse. Altough it was recommended using the _same_ CRT which
gives rise to the
shared static data issue.

Roland
Richard Howells
2004-11-25 17:06:10 UTC
Permalink
I think the classic example would be errno. If a call in your DLL set errno
and you attempted to check errno back in your EXE then:

- if you link BOTH with the DLL version you will both share the same errno
and will get the error code correctly

- if EITEHR is linked with the static library you will be using DIFFERENT
errno variables and will get the wrong error code.

Does that help?

- R

-----Original Message-----
From: boost-users-***@lists.boost.org
[mailto:boost-users-***@lists.boost.org] On Behalf Of Roland Schwarz
Sent: 25 November 2004 11:59
To: boost-***@lists.boost.org
Subject: Re: [Boost-users] Re: Memory leak reported using threads library
Post by Richard Howells
There are traps in the MS world. Some CRT functions (think strtok - yuk)
use static data. If you build with the statically linked version of the
library, each executable (.exe AND .dll) has it's own copy of that static
data and they don't know about each other.
All executables built with the dynamically linked version share the same
copy of that static data.
If you use the dynamically linked version then you should (on Win NT and up
systems - not Win 9x) share the same copy of the code with all other apps in
the system that use the CRT.
I can understand this. But I cannot see why this will be a problem.
Case 1):
Singgle threaded: As long as one isn't calling functions that modify
this data in between
no harm is done, whether two instances of static data or not.
Case 2):
Multi threaded: Every thread has its own local copy of static data in
TLS storage.
No harm again.

But perhaps I am still simply not beeing able to see the trap?

BTW.: Having a separate copy of the data in the (boostified) DLL will
improve robustness, not
making it worse. Altough it was recommended using the _same_ CRT which
gives rise to the
shared static data issue.

Roland


_______________________________________________
Boost-users mailing list
Boost-***@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.797 / Virus Database: 541 - Release Date: 15/11/2004


---
Outgoing mail is Virus checked.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.797 / Virus Database: 541 - Release Date: 15/11/2004
Joaquin M Lopez Munoz
2004-11-25 12:11:34 UTC
Permalink
Post by Roland Schwarz
I inadvertently replied to the wrong posting.
Post by John Maddock
That's your problem: there must be one single rtl shared both by your
code and the Boost.Threads dll: and that means using the dynamic C
runtime.
That surprises me somewhat.
mydll depending on dynamic CRT.
myapp depending on static CRT and depending on mydll.
You think this is not possible?
Just tried it. Found no obvious problem. Are there hidden traps?
This is an old-time problem MSVC programmers keep
stumbling upon. As John points out, the only safe alternative
is that every executable (EXE or DLL) in an app uses the
same *dynamic* version of the CRT: all of them debug dynamic
or all of them release dynamic. Every other option will
casue you trouble.

The biggest source of incompatibilites has to do with memory
allocation. MSVC malloc/free (and new/delete) implementation
uses an internal heap allocated at CRT initialization time.
Every instance of the CRT has its own internal heap. Now,
if module (EXE or DLL) A allocates some memory and
module B tries to free it through another copy of the CRT,
an instant crash is guranteed, because the memory
does not belong in B's internal heap. Try it: select static
CRT for every module, allocate some memory in your EXE
and let some DLL try to free that memory.

When everybody selects dynamic CRT, there's only
one copy of it across the app, and you'll find no problem.

If you restrict yourself to C-style calls where no
ownership of memory is transferred, then everything is OK,
but this is hardly possible in Boost libraries where C++ objects
are passed around.

In the case where the boundary between the EXE and the
DLL is crossed only by object *pointers*, the problem still
remains if a module tries to delete a pointer not allocated
within its CRT, but in this case there's a simple workaround:
if the class being pointed to has a virtual destructor,
then it is safe to delete a pointer everywhere, since the
destruction code, being virtual, will get executed within
the module where the object was created (as the vtable
will be pointing to that module).

Hope this sheds some light on the issue.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
a***@ati-uk.com
2004-11-24 12:49:41 UTC
Permalink
Post by gast128
I am working now on a project, which solution consists of 73 vc-projects
(more
Post by gast128
than 2500 files) and it does not leak memory in its main loop, thanks to
the
Post by gast128
debug crt of m$. We have overwritten the new and delete operator like m$
in
Post by gast128
MFC does so we get accurate memory leak reporting. If you take this
business
Post by gast128
serious one can not allow any memory leak reported by the debug crt.
Of course, malloc and new are not the only ways to consume memory. Virtual
Memory, Memory Mapped files, COM memory allocation functions etc etc. And
the leak can be in library code over which we have much less control (other
than to not use it) and therefore weaker support for leak finding and
detection.

It turns out we don't have a leak anywhere in our code. If we don't use
boost::thread then no leak, if we use boost::thread and use CRT dynamically
rather then statically then no leak.
Post by gast128
Multithreaded configurations of MSVCRT allocates some per-thread memory
as needed, e.g. for the object that localtime returns a pointer to. To
ensure that this memory is freed at thread exit, you must either use a
DLL configuration of the CRT or ensure that all threads that call into
it are started using the _beginthread or _beginthreadex function. The
Boost.Thread DLL is not (and cannot be) linked to the same CRT that is
statically linked into your executable, so neither of these conditions
is satisfied.
If I remember correctly, any memory allocated in your executable cannot
be deallocated in the Boost.Thread DLL, or vice versa, since they have
separate heaps. I would expect an attempt to do so to result in a
crash, but it might in some cases be silently ignored, resulting in a
leak.


I have considered this and it still may be the answer or lead to an answer.

Yes indeed they have separate heaps

It may explain why the leak is steeper depending on what the function does.
However I do remember had one experiment where i filled up a vector with a
load of stuff and hey presto, no leak.

if I have a function that allocates and deallocates memory on the heap and I
use it as a thread using boost::thread, then when memory deallocations are
performed by that thread is it the boost dll that is doing the deallocation
or is it my exe?

One would assume it was my exe since the deallocation code is in my exe.
Surely there is no code in the threads dll to deallocate my memory.

And I never ever get a crash, just a leak.
Ben Hutchings
2004-11-24 14:04:38 UTC
Permalink
***@ati-uk.com wrote:
<snip>
Post by a***@ati-uk.com
Post by Ben Hutchings
Multithreaded configurations of MSVCRT allocates some per-thread memory
as needed, e.g. for the object that localtime returns a pointer to. To
ensure that this memory is freed at thread exit, you must either use a
DLL configuration of the CRT or ensure that all threads that call into
it are started using the _beginthread or _beginthreadex function. The
Boost.Thread DLL is not (and cannot be) linked to the same CRT that is
statically linked into your executable, so neither of these conditions
is satisfied.
If I remember correctly, any memory allocated in your executable cannot
be deallocated in the Boost.Thread DLL, or vice versa, since they have
separate heaps. I would expect an attempt to do so to result in a
crash, but it might in some cases be silently ignored, resulting in a
leak.
I have considered this and it still may be the answer or lead to an answer.
Yes indeed they have separate heaps
It may explain why the leak is steeper depending on what the function does.
As might the on-demand allocations by the CRT.
Post by a***@ati-uk.com
However I do remember had one experiment where i filled up a vector with
a load of stuff and hey presto, no leak.
Right, because its memory is automatically freed in the same context as
it is allocated.
Post by a***@ati-uk.com
if I have a function that allocates and deallocates memory on the heap
and I use it as a thread using boost::thread, then when memory
deallocations are performed by that thread is it the boost dll that is
doing the deallocation or is it my exe?
It is your executable, of course.
Post by a***@ati-uk.com
One would assume it was my exe since the deallocation code is in my exe.
Surely there is no code in the threads dll to deallocate my memory.
Right. However, if part of Boost.Thread is compiled inline in your
executable, any (de)allocations that part performs will be done using
your executable's heap.
Post by a***@ati-uk.com
And I never ever get a crash, just a leak.
Really I don't see a whole lot of point trying to work out exactly
what's going wrong here. Given that there are well-known problems with
statically linking to the CRT while dynamically linking to C++
libraries, which can be fixed by dynamically linking to the CRT, why not
just do that?

Ben.
Loading...