problem mit doppeltem destruktor-aufruf



  • hallo leut,
    folgendes problem (hoffe habt ne idee):

    a.h:

    class A
    {
     static libtype s_lib;
    };
    

    a.cpp:

    #include <a.h>
    libtype A::s_lib;
    

    b.h:

    #include <a.h>
    class B
    {
     public:
     void SomeFunction();
     static libtype B::s_lib;
    
    };
    

    b.cpp:

    #include <b.h>
    libtype B::s_lib;
    void B::SomeFunction()
    {
     ...
    }
    

    main.cpp:

    #include <b.h>
    int main(int argc, char *argv[])
    {
     A a;
     B b;
     b.SomeFunction();
     return 0;
    }
    

    Das Problem ist, dass der Destruktor der statischen Member A::s_lib bei Beendigung von main.cpp zweimal aufgerufen wird (es handelt sich um einen destruktor einer library), und dieser destruktor schmeisst eine assertion
    falls das objekt schoneinmal destruiert wurde.

    Warum der doppelte Destruktor Aufruf und wie koennte man sowas verhindern (einen Zeiger zu verwenden und diesen bei Destruierung auf NULL zu setzen um beim naechsten mal zu schauen ob dieser bereits auf NULL gesetzt wurde, solle keine option sein)

    danke vorab.



  • Du kannst anscheinend nicht mehrere Instanzen von libtype anlegen, weil irgendwelche Ressourcen in der lib geteilt werden.
    Dein Programm darf also nur eine Instanz von libtype benutzen.
    Der doppelte Dtor aufruf kommt, weil der Dtor von libtype einmal von A::s_lib und einmal von B::s_lib aufgerufen wird.



  • sicher das das der grund sein soll?

    es sind ja zwei verschiedene instanzen (nur vom gleichem typ).
    das problem ist der zweimalige aufruf des destruktor einer (!) instanz.



  • Ja ziemlich. Das wird irgendwie so aussehen:

    //in der lib
    
    void initSystem() //irgendwas in der lib, dass nur einmal beim start aufgerufen werden darf
    {
        //hier werden z.B. irgendwelche globalen heapobjekte angelegt
    }
    
    void shutdwonSystem() //irgendwas in der lib, dass nur einmal beim beenden aufgerufen werden darf
    {
        //hier wird aufgeräumt
    }
    
    //darf nur einmal instaziiert werden, sollte also besser ein singleton sein
    //ist es aber nicht. daher das problem
    class libtype 
    {
    public:
        libtype(){ initSystem(); }
        ~libtype(){ shutdwonSystem(); }
    };
    
    //client code
    
    #include <libtype_interface.h>
    
    int main()
    {
        libtype A;
        libtype B;
        //...
    
        //Dtor von B -> okay
        //Dtor von A -> boing (es wird aufgeräumt, was schon aufgeräumt wurde)
    }
    


  • so einfach ist das glaube ich nicht.

    bei dem besagten libtype handelt es sich in meiner app genauer um eine boost-scope-lock instanz (falls jemand das kennen sollte).

    ein singleton ist hier kein option, ich brauche definitiv zwei instanzen.

    der grund (und eine moegliche loesung) fuer die doppelte zerstoerung einer dieser beiden statischen member ist also immer noch offen :))



  • Wie wäre es denn damit, wenn Du mal konkreten Code rausrückst. Ich wette, wenn Du in Deinem Beispiel oben in A oder B die libtype Instanz weglässt, dann geht es, weil nur einmal etwas aufgerufen wird, dass nur einmal aufgerufen werden darf.
    Und boost::scoped_lock ist eben gerade für die Benutzung in einem Scope gedacht. Das widerspricht der Benutzung als globales statisches Objekt aber komplett. Vermutlich wird im unterliegenden Mutex unlock aufgerufen, und der aufrufende Thread ist nicht der Owner (also der Thread der vorher auch lock aufgerufen hat).



  • wens interessiert: ein pragma ones in b.h loest das problem.
    trotzdem danke fuer alles.


Anmelden zum Antworten