destroy singleton?

Discussion in 'C++' started by Ron Eggler, Apr 10, 2008.

  1. Ron Eggler

    Ron Eggler Guest

    Hi,

    I created a singleton class and can't get rid of it anymore ;)
    Uhm, the important things in the definition look like that:
    [header]
    class GPIOcontrol: public TSPThread
    {
    public:
    static GPIOcontrol* instance(GPSData*); //Method returns pointer of
    singleton instance of this class
    ~GPIOcontrol();
    static GPIOcontrol* pinstance; //The instance pointer that is returned
    by the method instance() - this is a singleton class

    protected:
    GPIOcontrol(GPSData *gpsDataObj);

    private:
    };

    void PrepareToDie(void); //This method unsets the singleton pointer
    [/header]
    I call the PrepareToDie() function from the destructor and get a
    segmentation fault, the implementation of this function looks like:
    [implementation]
    void PrepareToDie(void) //This method unsets the singleton pointer
    {
    delete GPIOcontrol::pinstance;
    }
    [/implementation]
    I first had thsi delete PrepareToDie function as a public method in the
    class what returned me a seg. fault so i thought i could resolve it by
    moving it out of the class but it apparently wouldn't work.
    Does anyone know how i can get rid of it and free its memory?

    Thank you for hints & suggestions!
    Ron
    --
    weeks of software enineering safe hours of planing ;)
     
    Ron Eggler, Apr 10, 2008
    #1
    1. Advertising

  2. Ron Eggler

    Christopher Guest

    On Apr 10, 5:09 pm, Ron Eggler <> wrote:
    > Hi,
    >
    > I created a singleton class and can't get rid of it anymore ;)
    > Uhm, the important things in the definition look like that:
    > [header]
    > class GPIOcontrol: public TSPThread
    > {
    > public:
    > static GPIOcontrol* instance(GPSData*); //Method returns pointer of
    > singleton instance of this class
    > ~GPIOcontrol();
    > static GPIOcontrol* pinstance; //The instance pointer that is returned
    > by the method instance() - this is a singleton class
    >
    > protected:
    > GPIOcontrol(GPSData *gpsDataObj);
    >
    > private:
    >
    > };
    >
    > void PrepareToDie(void); //This method unsets the singleton pointer
    > [/header]
    > I call the PrepareToDie() function from the destructor and get a
    > segmentation fault, the implementation of this function looks like:
    > [implementation]
    > void PrepareToDie(void) //This method unsets the singleton pointer
    > {
    > delete GPIOcontrol::pinstance;
    > }
    > [/implementation]
    > I first had thsi delete PrepareToDie function as a public method in the
    > class what returned me a seg. fault so i thought i could resolve it by
    > moving it out of the class but it apparently wouldn't work.
    > Does anyone know how i can get rid of it and free its memory?
    >
    > Thank you for hints & suggestions!
    > Ron
    > --
    > weeks of software enineering safe hours of planing ;)



    If its a singleton, then it should not be deleted until program exit.
    There are many singleton patterns, one of which uses a reference
    instead of a pointer, in order to rely on the program exit to release
    it. I'd look over some of those. Also keep in mind the problems with
    singletons and be sure you are handling them or IMO avoiding using
    singletons to avoid the problems!

    Google "static initialization fiasco"
    Read up on global and static deallocation at program exit time, and
    note the order is undefined! This caused a slew of bugs in the code
    I've seen in the past.

    IMHO it is better to avoid them altogether and create an instance of
    the class at program start-up and then pass references to it around
    instead. that way you can control init and release order. Especially
    when it is obvious that one global,static (singleton) depends on
    another.

    Anyway, the obvious ism, your pointer is probably null by the time the
    destructor gets called.
     
    Christopher, Apr 10, 2008
    #2
    1. Advertising

  3. Ron Eggler

    Ron Eggler Guest

    Andy Champ wrote:

    > Ron Eggler wrote:
    >>
    >> Thank you for hints & suggestions!
    >> Ron

    >
    > In the code you've supplied, you haven't initialised pinstance. Either
    > we're missing something - or you are... Also, you haven't shown what
    > else you do after the delete, nor what steps you take to make sure it
    > doesn't get deleted more than once.


    i do initialize pinstance like this:
    Code:
    GPIOcontrol * GPIOcontrol::instance(GPSData *gpsDataObj)
    {
            if (pinstance==NULL){//if this singleton hasn't been created yet...
                    pinstance=new GPIOcontrol(gpsDataObj);          
            }       
            return pinstance;       
    }
    
    and before the delete command i check if it's "!=NULL" so that should be
    fine.

    > What's a TSPThread?


    That's a class handling threads, it just initializes and destoys the thread.
    it also offers flags to check if the thread is running already.
    The header looks like:
    [tshpthread.h]
    class TSPThread
    {
    public:
    ////////////////////////////////////////////////////////////////////////////////////
    /// This method check to see the thread is still active or not
    ///@return bool true thread is still running
    /// false thraed end already
    ////////////////////////////////////////////////////////////////////////////////////
    bool IsActive(){return (m_pThread == 0?false:true);};

    ///The entry point of the thread, after TSPThread class was create, call
    this method to start the real thread
    ///This method also make sure for every TSPThread instance, there's only
    one thread runs
    void start();

    ///Constructor
    TSPThread();

    ///Destructor
    virtual ~TSPThread();

    // a global flag that can be set to true by a class above to end the
    thread(s)
    bool EndFlag;

    protected:

    ////////////////////////////////////////////////////////////////////////////////////
    ///This method suppose to tell upper module the thread is terminated
    already or not.
    ///@return true The thread is stopped already, it's safe to remove it from
    memroy.
    /// false The thread is still active, please wait
    ////////////////////////////////////////////////////////////////////////////////////
    bool GetStopFlag(){return m_bStopThread;};

    private:

    ////////////////////////////////////////////////////////////////////////////////////
    ///This is the pure virutal function, all subclass should implement this
    fucntion. All stuff
    ///You wanna do in the thread whould go here.
    ////////////////////////////////////////////////////////////////////////////////////
    virtual void run()=0;

    ////////////////////////////////////////////////////////////////////////////////////
    ///This is a helper function for TSPThread, it makes class TSPThread know
    nothing about
    ///subclass, but subclass keeps all features as a normal class.
    ///@param void *i_ptr The pointer of current subclass object
    ///@return static void * Dummy type for pthread_create
    ////////////////////////////////////////////////////////////////////////////////////
    static void *StartThread(void *i_ptr);

    ///The flag for thread is created already or not
    bool m_bThreadAlready;

    ///Flag forcurrent thread is stopped or not
    bool m_bStopThread;

    ///The handler for current thread
    pthread_t m_pThread;

    ///Mutex for thread creation critical section
    pthread_mutex_t mutex_single;


    };
    [/tshpthread.h]

    --
    weeks of software engineering safe hours of planning ;)
     
    Ron Eggler, Apr 11, 2008
    #3
  4. Ron Eggler

    Ron Eggler Guest

    Christopher wrote:

    > On Apr 10, 5:09 pm, Ron Eggler <> wrote:
    >> Hi,
    >>
    >> I created a singleton class and can't get rid of it anymore ;)
    >> Uhm, the important things in the definition look like that:
    >> [header]
    >> class GPIOcontrol: public TSPThread
    >> {
    >> public:
    >> static GPIOcontrol* instance(GPSData*); //Method returns pointer
    >> of
    >> singleton instance of this class
    >> ~GPIOcontrol();
    >> static GPIOcontrol* pinstance; //The
    >> instance pointer that is returned
    >> by the method instance() - this is a singleton class
    >>
    >> protected:
    >> GPIOcontrol(GPSData *gpsDataObj);
    >>
    >> private:
    >>
    >> };
    >>
    >> void PrepareToDie(void); //This
    >> method unsets the singleton pointer
    >> [/header]
    >> I call the PrepareToDie() function from the destructor and get a
    >> segmentation fault, the implementation of this function looks like:
    >> [implementation]
    >> void PrepareToDie(void) //This
    >> method unsets the singleton pointer
    >> {
    >> delete GPIOcontrol::pinstance;
    >> }
    >> [/implementation]
    >> I first had thsi delete PrepareToDie function as a public method in the
    >> class what returned me a seg. fault so i thought i could resolve it by
    >> moving it out of the class but it apparently wouldn't work.
    >> Does anyone know how i can get rid of it and free its memory?
    >>
    >> Thank you for hints & suggestions!
    >> Ron
    >> --
    >> weeks of software enineering safe hours of planing ;)

    >
    >
    > If its a singleton, then it should not be deleted until program exit.


    It is at the program exit where i want to delete it.

    > There are many singleton patterns, one of which uses a reference
    > instead of a pointer, in order to rely on the program exit to release
    > it. I'd look over some of those. Also keep in mind the problems with
    > singletons and be sure you are handling them or IMO avoiding using
    > singletons to avoid the problems!


    Will keep in mind for future designs....

    > Google "static initialization fiasco"
    > Read up on global and static deallocation at program exit time, and
    > note the order is undefined! This caused a slew of bugs in the code
    > I've seen in the past.


    Oh wow, haven't heard of that but shouldn't be applicable in my application
    >
    > IMHO it is better to avoid them altogether and create an instance of
    > the class at program start-up and then pass references to it around
    > instead. that way you can control init and release order. Especially
    > when it is obvious that one global,static (singleton) depends on
    > another.
    >
    > Anyway, the obvious ism, your pointer is probably null by the time the
    > destructor gets called.


    negative, it isn't. :(

    --
    weeks of software engineering safe hours of planning ;)
     
    Ron Eggler, Apr 11, 2008
    #4
  5. Ron Eggler

    Christopher Guest

    On Apr 10, 6:26 pm, Ron Eggler <> wrote:
    > Andy Champ wrote:
    > > Ron Eggler wrote:


    [snip]

    > i do initialize pinstance like this:


    > GPIOcontrol * GPIOcontrol::instance(GPSData *gpsDataObj)
    > {
    > if (pinstance==NULL){//if this singleton hasn't been created yet...
    > pinstance=new GPIOcontrol(gpsDataObj);
    > }
    > return pinstance; }


    [snip]


    1) The singleton was initialized with a GPDData object A, but what if
    you call GPIOcontrol::instance() with GPSData object B, in which case
    it gives you back the singleton initialized with A???
    1a) If you take a parameter during initialization, your object might
    not be a candidate for a singleton
    1a1) After all, if it is to always exist and there can be only one, it
    can only be initialized one way... at least for the life of the
    process.
    2) Do you not care if an invalid or NULL GPSData object was passed as
    a parameter?
    3) Since GPSData is being passed in as a pointer, who allocated it?
    who is going to destroy it? Is your singleton attempting to destroy it
    when someone else already did? Or perhaps it is another global object
    whom was destroyed during program exit before the singleton?
     
    Christopher, Apr 11, 2008
    #5
  6. Ron Eggler

    James Kanze Guest

    On Apr 11, 12:09 am, Ron Eggler <> wrote:

    > I created a singleton class and can't get rid of it anymore ;)


    That's usually a feature, not a bug, where singletons are
    concerned. In general, I avoid ever deleting a singleton.

    > Uhm, the important things in the definition look like that:
    > [header]
    > class GPIOcontrol: public TSPThread
    > {
    > public:
    > static GPIOcontrol* instance(GPSData*);
    > // Method returns pointer of singleton
    > // instance of this class
    > ~GPIOcontrol();
    > static GPIOcontrol* pinstance;
    > // The instance pointer that is returned
    > by the method instance() - this is a singleton class
    >
    > protected:
    > GPIOcontrol(GPSData *gpsDataObj);
    >
    > private:
    > };


    > void PrepareToDie(void);
    > // This method unsets the singleton pointer
    > [/header]
    > I call the PrepareToDie() function from the destructor and get
    > a segmentation fault, the implementation of this function
    > looks like:


    From the destructor of what?

    > [implementation]
    > void PrepareToDie(void)
    > //This method unsets the singleton pointer
    > {
    > delete GPIOcontrol::pinstance;
    > }
    > [/implementation]
    > I first had thsi delete PrepareToDie function as a public
    > method in the class what returned me a seg. fault so i thought
    > i could resolve it by moving it out of the class but it
    > apparently wouldn't work. Does anyone know how i can get rid
    > of it and free its memory?


    Most of the time, it is preferable not to delete the singleton,
    ever. That way, it remains accessible even in destructors of
    static objects. In the rare cases where deletion is necessary,
    the usual solution I've seen is to use a local static:

    GPIOcontrol*
    GPIOcontrol::instance()
    {
    static GPIOcontrol theOneAndOnly ;
    return theOneAndOnly ;
    }

    In this case, the compiler takes care of ensuring that the
    object is only created once, and that the destructor is called
    once during program shutdown.

    (Note that this will only work in a multithreaded environment if
    you can ensure that instance is called at least once before
    threads are started, or that it is only called from a single
    thread. Otherwise, you need a scoped lock before the static.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 11, 2008
    #6
  7. Ron Eggler

    Brian Tyler Guest

    Brian Tyler, Apr 11, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ook
    Replies:
    2
    Views:
    359
  2. Proton Projects - Moin

    Singleton - Whether Cloneable overrides Singleton

    Proton Projects - Moin, Mar 26, 2007, in forum: Java
    Replies:
    4
    Views:
    3,337
    Proton Projects - Moin
    Mar 27, 2007
  3. requinham
    Replies:
    11
    Views:
    2,371
    Michael Doubez
    Feb 19, 2010
  4. Wilhelm
    Replies:
    1
    Views:
    187
  5. Trans
    Replies:
    12
    Views:
    305
    Robert Klemme
    Sep 14, 2007
Loading...

Share This Page