Jens Seidel ha escrito:
On Wed, Jan 30, 2008 at 01:41:15PM +0000, Martin Fisher wrote:
Using the boost_1_35_0 svn library download and Visual C++ 2008 Express
edition.
Originally compiled as a CLR program. Recompiling using native Win32
still gives a crash during program termination - in
atomic_count_win32.hpp in operator-- (BOOST_INTERLOCKED_DECREMENT)
Unhandled exception at 0x010752b9 in fly2.exe: 0xC0000005: Access
violation writing location 0x00779040.
There is indeed a bug somewhere. I could reproduce it on Linux which
doesn't suffer from CLR/libc/... mess. I just compiled it (code from
trunk) and it crashes. valgrind reports:
[...]
Jens, Martin,
I could also reproduce it here, and found the reason for the crash. Please
follow me:
The static initialization of flyweight<string>'s internal factory (explained in detail at
http://tinyurl.com/2rwwug ) is done automatically before the first use of
flyweight<string> in the program, or before main() at the very latest. But now
let's take a look again at Martin's program:
vector vec;
...
int main(int argc, char* argv[])
{
...
}
The static initialization of vec invokes vector ctor, but
this ctor *does not use boost::flyweight<string>*: no flyweight objects are created
during the default initialization of the vector. So, boost::flyweight<string>'s factory
is not guaranteed to be initialized before vec, only before main()! Consequently,
the following is a valid sequence of static initializations and destructions (which
go in reverse order as the corresponding initializations):
// initialziation of vec
vector vec;
// (automatic) initialization of boost::flyweight<string>'s factory
...
int main(int argc, char* argv[])
{
...
}
// automatic destruction of boost::flyweight<string>'s factory
// automatic destruction of vec
And this is the problem: when the factory is destroyed, there are still
flyweight objects around (those in vec), when there should be none,
and on vec's destruction time the flyweight objects point to deallocated
memory, hence the crash.
This is solved by forcing boost::flyweight<string> static initialization
before that of vec:
boost::flyweights::flyweight<string>::initializer init;
vector vec;
So that static initialization order is correct. Could you please try the fix?
This is a fundamental issue for which I see no easy *automatic* fix upon first
reflection, other than documenting very clearly the situations in which it
can arise. Comments and suggestions welcome.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo