views:

3782

answers:

8

Recently I've bumped into realization/implementation of Singleton design pattern for C++. It has looked in the following way (I have adopted it from real life example):

// a lot of methods is omitted here
class Singleton
{
   public:
       static Singleton* getInstance( );
       ~Singleton( );
   private:
       Singleton( );
       static Singleton* instance;
};

From this declaration I can deduce that instance field is initiated on the heap, that means there is a memory allocation. That is completely unclear for me is when does exactly memory is going to be deallocated? Or there is a bug and memory leak? It seems like there is a problem in implementation.

PS. And main question how to implement it in the right way?

+9  A: 

Being a Singleton, you usually do not want it to be destructed.

It will get torn down and deallocated when the program terminates, which is the normal, desired behavior for a singleton. If you want to be able to explicitly clean it, it's fairly easy to add a static method to the class that allows you to restore it to a clean state, and have it reallocate next time it's used, but that's outside of the scope of a "classic" singleton.

Reed Copsey
and I was just about to click "Post" as your, almost identical to mine, answer appeared :)
Damir Zekić
if delete is never explicitly called on the static Singleton* instance, wouldn't this still technically be considered a memory leak?
Andrew Garrison
But what I need to do if I've opened some system resources and want to free them, before I finish, as well I want it to happen automatically. On solution, which comes to my head is to somehow adopt use of smart pointers here.
Artem Barger
Yes, but it's kind of a memory leak by design. This is one reason why many people feel that Singleton's have a code smell - they kind of break the rules on purpose. They're really just a way to encapsulate a global variable a bit more cleanly than a global, but the same arguments against globals are true against Singletons, including non-deterministic cleanup. See my note about extending it with a cleanup - if you called that during your app teardown (ie: deleted the static), you'd call the destructor, and avoid this situation.
Reed Copsey
It's not a memory leak anymore than a simple declaration of a global variable.
ilya n.
You can use RAII idioms to delete the singleton if you really need to. Better, IMHO, is to use the Meyers Singleton pattern described by Cătălin Pitiș.
anon
@ilya n. memory was allocated but wasn't freed that exactly memory leak and it doesn't matter what is the scope of variable.
Artem Barger
If you want to be freeing the resource, I'm suspicious that singleton might not be the right tool here. Regardless, I'm not seeing why you couldn't make a "destroy()" method that freed the memory and set the pointer to NULL. Ensuing calls to getInstance() will simply reallocate the memory.
jkerian
@Neil can you please give me a reference?
Artem Barger
To set something straight... "memory leak" concerns vis-a-vis singletons are completely irrelevent. If you have stateful resources in which deconstruction order matters, singletons can be dangerous; but all of the memory is cleanly regained by the operating system on program termination... nullifying this totally academic point in 99.9% of cases.If you want to argue the grammar back and forth of what is and is not a "memory leak", that's fine, but realize that it's a distraction from actual design decisions.
jkerian
@Artem - I can...see ***this*** thread :)
Robert Lamb
@jkerian: Memory leaks and destruction in the C++ context is not really about the memory leaking. Really it is about resource control. If you leak memory the destroctor is not called and thus any resources associated with the object are not correctly released. Memory is just the simple example we use when teaching programming but there are much more complex resources out there.
Martin York
@Martin I agree with you completely. Even if the only resource is memory, you will still get into trouble trying to find REAL leaks in your program if you have to wade through a list of leaks, filtering out ones that "don't matter." It is better to clean these all up so any tool that reports leaks only reports things that ARE a problem.
Dolphin
A: 

The desctructor should be in charge of releasing the memory. Can you show us the code in the ~Singleton() method?

Dan Lorenc
The question is about when that same destructor will be called :)
Damir Zekić
+5  A: 

You could avoid memory allocation. There are many variants, all having problems in case of multithreading environment.

I prefer this kind of implementation (actually, it is not correctly said I prefer, because I avoid singletons as much as possible):

class Singleton
{
private:
   Singleton();

public:
   static Singleton& instance()
   {
      static Singleton INSTANCE;
      return INSTANCE;
   }
};

It has no dynamic memory allocation.

Cătălin Pitiș
In some instances, this lazy initialization is not the ideal pattern to follow. One example is if the constructor of the singleton allocates memory from the heap and you wish that allocation to be predictable, for instance in an embedded system or other tightly controlled environment.I prefer, when the Singleton pattern is the best pattern to use, to create the instance as a static member of the class.
dominic hamon
For many larger programs, especially those with dynamic libraries. Any global or static object that's none primitive can lead to segfaults/crashes upon program exit on many platforms due to order of destruction issues upon libraries unloading. This is one of the reasons many coding conventions (including Google's) ban the use of non-trivial static and global objects.
obecalp
A: 

It is indeed probably allocated from the heap, but without the sources there is no way of knowing.

The typical implementation (taken from some code I have in emacs already) would be:

Singleton * Singleton::getInstance() {
 if (!instance) {
  instance = new Singleton();
 };
 return instance;
};

...and rely on the program going out of scope to clean up afterwards.

If you work on a platform where cleanup must be done manually, I'd probably add a manual cleanup routine.

Another issue with doing it this way is that it isn't thread-safe. In a multithreaded environment, two threads could get through the "if" before either has a chance to allocate the new instance (so both would). This still isn't too big of a deal if you are relying on program termination to clean up anyway.

T.E.D.
you can deduce, since you can see that instance variable is a pointer to the class instance.
Artem Barger
There is no need to dynamically allocate the singleton. In fact this is a bad idea as there is not way to automatically de-allocate using the above design. Let it fall out of scope is does not call destructors and is just lazy.
Martin York
You can automatically deallocate using the atexit function. That's what we do (not saying it's a good idea)
Joe
A: 

Another non-allocating alternative: create a singleton, say of class C, as you need it:

singleton<C>()

using

template <class X>
X& singleton()
{
    static X x;
    return x;
}

Neither this nor Cătălin's answer is automatically thread-safe in current C++, but will be in C++0x.

James Hopkin
Currently under gcc it is thread safe (and has been for a while).
Martin York
The problem with this design is that if used across multiple libraries. Each library has is own copy of the singelton that that library uses. So it is no longer a singelton.
Martin York
+21  A: 

See this article for a simple design for a lazy evaluated with guaranteed destruction singelton:
http://stackoverflow.com/questions/270947/can-any-one-provide-me-a-sample-of-singleton-in-c/271104#271104

The classic lazy evaluated and correctly destroyed singelton.

class S
{
    public:
        static S& getInstance()
        {
            static S    instance; // Guaranteed to be destroyed.
                                  // Instantiated on first use.
            return instance;
        }
    private:
        S();
        // Dont forget to declare these two. You want to make sure they
        // are unaccessable otherwise you may accidently get copies of
        // your singelton appearing.
        S(S const&);              // Don't Implement
        void operator=(S const&); // Don't implement
};

See this article about when to use a singelton: (not often)
http://stackoverflow.com/questions/86582/singleton-how-should-it-be-used

See this two article about initialization order and how to cope:
http://stackoverflow.com/questions/211237/c-static-variables-initialisation-order/211307#211307
http://stackoverflow.com/questions/335369/finding-c-static-initialization-order-problems/335746#335746

See this article describing lifetimes:
http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-a-c-function

See this article that discusses some threading implications to singeltons:
http://stackoverflow.com/questions/449436/singleton-instance-declared-as-static-variable-of-getinstance-method/449823#449823

See this article that explains why double checked locking will not work on C++ http://stackoverflow.com/questions/367633/what-are-all-the-common-undefined-behaviour-that-c-programmer-should-know-about/367690#367690

Martin York
+1 For Meyers singleton simplicity and good links. Note: private cons is not necessary (will not be generated) since you already have a cons (copy one) declared.
fnieto
@fnieto: Thanks. What I was trying to imply with the constructor S() should be declared private. As singeltons will have other members (otherwise why have a singelton) that need to be initialized (note there is __not__ a Don't implement), so when you do declarea a constructor it will need to be private.
Martin York
Good answer. But should note that this is not thread-safehttp://stackoverflow.com/questions/1661529/is-meyers-implementation-of-singleton-pattern-thread-safe
Varuna
Already noted above in: http://stackoverflow.com/questions/449436/singleton-instance-declared-as-static-variable-of-getinstance-method/449823#449823
Martin York
A: 

The solution in the accepted answer has a significant drawback - the destructor for the singleton is called after the control leaves the "main" function. There may be problems really, when some dependent objects are allocated inside "main".

I met this problem, when trying to introduce a Singleton in the Qt application. I decided, that all my setup dialogs must be Singletons, and adopted the pattern above. Unfortunately, Qt's main class "QApplication" was allocated on stack in the "main" function, and Qt forbids creating/destroying dialogs when no application object is available.

That is why I prefer heap-allocated singletons. I provide an explicit "init()" and "term()" methods for all the singletons and call them inside "main". Thus I have a full control over the order of singletons creation/destruction, and also I guarantee that singletons will be created, no matter whether someone called "getInstance()" or not.

SadSido
Look like you've tried to use it in the wrong way.
Artem Barger
+1  A: 

This is about object life-time management. Suppose you have more than singletons in your software. And they depend on Logger singleton. During application destruction, suppose another singleton object uses Logger to log its destruction steps. You have to guarantee that Logger should be cleaned up last. Therefore, please also check out this paper: http://www.cs.wustl.edu/~schmidt/PDF/ObjMan.pdf

baris_a