
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<boost::flyweight<string> > vec; ... int main(int argc, char* argv[]) { ... } The static initialization of vec invokes vector<boost::flyweight<string> > 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<boost::flyweight<string> > 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<boost::flyweights::flyweight<string> > 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