c++ - Template member functions, static local variables and destruction order -


first of all, sorry english:

i've designed little library manage memory program uses. implements kind of shared object memory management purposes. have following classes (i omit other members , functions don't need here explain problem):

  • a parametric struct called packet contains subobject of type t , counter:
template<class t> struct packet {    t t;    unsigned counter; }; 
  • a parametric class called ptrstack: stack destructor calls delete each pointer stack contains, when destructor called:
template<typename t> struct ptrstack : public std::stack<t*> {   ~ptrstack()   {       while(!this->empty()) {         delete this->top();         this->pop();       }   } }; 
  • a class called pool static parametric function (and other code, of course) returning reference ptrstack:
class pool {    template<class t>    using stack_tp = ptrstack<packet<t> >;  public:    template<class t>    static stack_tp<t>& get()    {      static stack_tp<t> pool;       return pool;    } }; 
  • finally, parametric class shared_obj
template<typename t> class shared_obj { /* members (see below) */ }; 
  • user classes inherit shared_obj:
struct internals_t; // definition in .cpp source code (pimpl idiom).  // `shared_obj` uses pointer type parameter. class user_t : public shared_obj<internals_t> {   // member functions accessing internal pointer.    // `user_t` light. mantains pointer, used   // common object.   // moreover, can work dynamic objects without using new , delete   // since memory managed shared_obj }; 

construction, assignment/copies , destruction perform fundamentally following actions:

  • each time new shared_obj<t> wanted created, packet<t>* created in heap.
  • each time shared_obj<t> copied, counter of associated packet incremented.
  • each time destructor of shared_obj<t> called, counter of associated packet decremented.
  • if counter of associated packet reachs 0, associated pointer pushed on stack means of:
pool::get<t>().push(ptr); 
  • so, redefine first point of list: when new packet<t>* wanted created, , pool of type empty, new packet created in heap. if pool isn't empty, use "in-place" version of new:
new (pool::get<t>().top()) t(args); pool::get<t>().pop(); 

so, destruction delegated when program exits, , created memory reused.

enough explanations!!

my problem is: need other statics objects of type "user_t" (really, different object of different types inheriting shared_obj), of them produce memory leaks, , thing following reason:

  • that static objects being created before creation of associated pools, because of definition of packet_pool.get<t>() each type instantiated after definition: template definitions instantiated concrete type in first pointer of use , not template written. so, lexical order in files different definition order in translated unit.
  • in consequence, static objects being destructed after associated pools, because static objects deleted in inverse order of construction, , coincides definition order of translated unit.
  • when static objects destructed, associated counter reachs 0 , try pushed in destructed pool. throws crash.

my doubt following:

  • what concrete "definition order" instantiated template functions in translation unit? assumptions correct?

and here parallel question:

  • can problem related fact pool local static function or "get" function inlined (because it's function defined inside class)? mean, each "pool" (each stack) have internal linkage , have different pools same type in different translation units?


Comments

Popular posts from this blog

Line ending issue with Mercurial or Visual Studio -

java - Jtable duplicate Rows -

java - Run a .jar on Heroku -