Opened 13 years ago
Closed 11 years ago
#3658 closed Feature Requests (invalid)
Remove dependency on static initialization/destruction order
Reported by: | Andrey Semashev | Owned by: | Joaquín M López Muñoz |
---|---|---|---|
Milestone: | Boost 1.42.0 | Component: | flyweight |
Version: | Boost 1.41.0 | Severity: | Problem |
Keywords: | Cc: |
Description
The static_holder depends on the static initialization/destruction order, as it is implemented as a function-local static variable. If there are flyweights in the static or global variables, which are initialized lazilly, the flyweight value may get destroyed before the flyweights that refer to it. For example:
#include <iostream> #include <string> #include <boost/shared_ptr.hpp> #include <boost/flyweight.hpp> #include <boost/flyweight/key_value.hpp> struct A { int m_n; A(int n) : m_n(n) { std::cout << "A()" << std::endl; } ~A() { std::cout << "~A()" << std::endl; } bool operator== (A const& a) const { return m_n == a.m_n; } friend std::size_t hash_value(A const& a) { return a.m_n; } }; struct B { boost::flyweight< boost::flyweights::key_value< int, A > > m_A; B() : m_A(10) { std::cout << "B()" << std::endl; } ~B() { std::cout << "~B()" << std::endl; } }; boost::shared_ptr< B > p; int main(int, char*[]) { p.reset(new B()); return 0; }
Compiled with MSVC:
cl -Ox -MD -EHsc -I . -DNDEBUG ./flyweight_test.cpp
Produces:
A() B() ~A() ~B()
And a crash.
A possible solution would be to destroy flyweight values only when reference counter from flyweights drops to zero.
Change History (5)
comment:1 by , 13 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 13 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
That solution is not suitable for me because p and B and A are rather distant (they belong to different components of the application). In fact, the component that creates p doesn't know anything about A's implementation, and about flyweights in particular.
Why is it not possible to implement a fair reference counted semantics?
I reopen the ticket as I feel that this problem is not solved yet. This may not be a coding bug, but I believe this is a major design flaw that deserves to be addressed. If you have any objections or suggestions, we may discuss it either here or on the dev. ML.
comment:3 by , 13 years ago
Yes, please bring this to the mailing list so that we can discuss it in a more fluent manner. Thank you!
comment:5 by , 11 years ago
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
I'm re-closing this old one, as the suggestions on the mailing list discussion seem to me too cumbersome to implement, and basically break the orthogonality of the different concepts (factory, holder, values.) As suggested there, you can define your own holder that basically does not delete the factory, at the cost of a memory leak (if it can be called a leak, as this is not your normal leak where memory usage increases over time, which is the problematic case.)
The issue is a known limitation of static_holder that can't be dealt with in a more satisfactory manner than its current implementation. The solution requires some user help, as explained in
http://www.boost.org/libs/flyweight/doc/tutorial/technical.html#static_init
In your particular case, add the following before the line where p is declared: