none
atexit + static class member, clenaup RRS feed

  • Pregunta

  • Hi, I'm working with the following sheme:

    /* Class A definition */

    class A

    {

    private:

    static map<string,A *) _m;

    public:

    static void Clear();

    static void Add(string key, A *value);

    private:

    /* A internal */

    public: 

    /* A external */

    bool Init();

    void Start();

    void Stop();

    }

     

    void A::Clear() /* static funtion definition */

    {

    for (map<string, A*>::iterator i = _m.begin(); i != _m.end(); i = _m.erase(i))

    {

    i->second->Stop();

    delete i->second;

    }

    }

     

    void cleanup()

    {

    A::Clear();

    }

     

    int main(int argc, char **argv)

    {

    atexit(cleanup)

    for(...;...;...)

    {

    A* inst = new A();

    /* set A properties */

    A::Add(key, inst);

    inst->Start();

    }

    /* block until termination */

    A::Clear();

    }

     

    The program is a win32 console program. When I close the console window the program jumps from the blocking code (marked as 'block until termination' in the sample) to the clenaup function, then jumps to the A::Clear() function an executes nothing. I know there are objects inside the map because I've a breakpoint situated in destructor A::~A(), A::Clear() in main function is not called due to closing the window while in a previus wait, A::Clear is called from cleanup function but code inside is NOT executed. Why?

    lunes, 1 de agosto de 2011 8:59

Todas las respuestas

  • The problem was that A::Stop calls external library (dll) code. When atexit detects external code call it aborts.
    lunes, 1 de agosto de 2011 11:04
  • class A
     {
     private:
      ~A(void) {Clear();}
      //...
     };
    
    void A::Add(string key, A *value)
     {
     static A AparentementeNoHaceNada;
     // al ser static, sólo se creará una instancia
     // la primera vez que se ejecute.
     // cuando se acabe el programa el compilador
     // ya llamará al destructor
    
     // mas código para hacer el Add
     }
    
    
    


    No uses el atexit para limpiar. Usa el destructor de la clase

     

    lunes, 1 de agosto de 2011 14:17
  • El destructor no se llama, porque al cerrar la consola sólo se ejecuta la función atexit. 
    lunes, 1 de agosto de 2011 16:27
  • A no ser que abortes el programa en seco, todos los destructores de todas los objetos static que se hayan creado antes de un atexit() se llamarán después del '}' del main y antes de ejecutar las funciones indicadas en ese atexit. Si no hay atexit, sólo se ejecutaran los destructores. Es lo que dice el estandar y es lo que tiene que hacer el compilador.

     

     

    lunes, 1 de agosto de 2011 18:39