7

This is a simple singleton:

class Singleton
{
    Singleton();
    virtual ~Singleton();

    Singleton * Singleton::getInstance() 
    {
        static Singleton * instance;

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

When main code calls Singleton::getInstance()->someMethod() for the first time, isn't the class instantiated twice? Will be there memory leak?

I am asking because Visual Leak Detector detects memory leak on the line with new Singleton().

vladon
  • 8,158
  • 2
  • 47
  • 91
  • It's not quite a *leak*, since you never lose the reference to the memory. It's just not very tidy. To clean up, say `static std::unique_ptr instance;`. – Kerrek SB Jun 02 '15 at 17:39
  • you will need to provide a mechanism to destroy your singletons at shutdown - if you want to debug for memory leaks. otherwise let the OS clean up singleton instances that don't need to run shutdown-specific code (faster shutdown). – BeyelerStudios Jun 02 '15 at 17:41
  • 3
    This isn't a Singleton. `getInstance()` is not a static member so you need at least one object of class Singleton to call `getInstance()`, after which you have *two* Singleton objects. I don't know where instance is declared but no one seems to `delete` it ever. So -- yes you have a memory leak. – Oncaphillis Jun 02 '15 at 17:41
  • Wow look at all these answers-in-comments. Sigh. – Lightness Races in Orbit Jun 02 '15 at 17:48
  • @KerrekSB I think it's a leak because the destructor might not be called. – KABoissonneault Jun 02 '15 at 17:49
  • 2
    You should return a reference here, `static Singleton&`, and declare `static Singleton instance;` No need for additional checks etc, and it's also thread safe since C++11. – vsoftco Jun 02 '15 at 17:49
  • 2
    @vsoftco: You have an extra `&`. But you make a very good point. – Lightness Races in Orbit Jun 02 '15 at 17:50
  • 1
    @LightnessRacesinOrbit just removed it :) – vsoftco Jun 02 '15 at 17:51
  • 2
    @vsoftco: Stole your idea for my answer – Lightness Races in Orbit Jun 02 '15 at 17:53
  • @KABoissonneault: It depends on how specific you get in your definition of "leak". A "definite leak" is one which is unfixable, like "new int;" whereas "int * p = new int;" is potentially fixable (by calling `delete`). Some call the latter "still reachable (but not freed)". – Kerrek SB Jun 02 '15 at 21:00

3 Answers3

18

When main code calls Singleton::getInstance()->someMethod() for the first time, isn't the class instantiated twice?

No. Calling a static member of Singleton does not instantiate Singleton, so the only instance of Singleton to exist here is the one you create with new. And you only create it once, because once instance points to it, you never call new again.

One problem you have here, however, is that you failed to make getInstance a static member function. I assume this is a typo/oversight since, otherwise, your program would not even compile. In fact, the declaration is ill-formed even as a non-static member. Furthermore, the constructor should be private to enforce the notion that only getInstance may instantiate the type.

Will be there memory leak?

Yes, and this is what Leak Detector is reporting. However, it's minimal: the problem is that there is nothing to delete that singleton instance right before your program shuts down.

Frankly I wouldn't worry about it. This may be one of those rare times that a leak is acceptable, mostly because more than a "leak" it's just a one-time failure to de-allocate on process shutdown.

However, if you get rid of the pointer entirely then you can avoid both problems at the same time, since one of the last things your program does will be to destroy objects of static storage duration:

#include <iostream>

class Singleton
{
public:
    ~Singleton()  { std::cout << "destruction!\n"; }

    static Singleton& getInstance() 
    {
        static Singleton instance;
        return instance;
    }

    void foo() { std::cout << "foo!\n"; }

private:
    Singleton() { std::cout << "construction!\n"; }
};

int main()
{
    Singleton::getInstance().foo();
}

// Output:
//   construction!
//   foo!
//   destruction!

(live demo)

No need even for a pointer!

This has the added benefit that the entire function becomes inherently thread-safe, at least as of C++11.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • "Calling a static member..." - should `getInstance()` be static? – vladon Jun 02 '15 at 17:42
  • @Vladon ah yes it should. It seems that's the clear intent, though, despite the incorrect syntax. – Lightness Races in Orbit Jun 02 '15 at 17:42
  • Noting that in the case of Visual Studio, it's only thread-safe as of Visual Studio 2015. – KABoissonneault Jun 02 '15 at 17:56
  • 1
    @KABoissonneault: lolsrsly? Not that I'm surprised. Anyway I'll let the reader find out what parts of C++11 his implementation actually supports. – Lightness Races in Orbit Jun 02 '15 at 17:56
  • Another problem with the pointer version is that its destructor is never called which may or may not be an issue. – Galik Jun 02 '15 at 17:57
  • @Galik: Well, okay, I suppose I've used the term "de-allocate" a little too much here. I mean "destroy" in the broader sense, including invocation of destructors. – Lightness Races in Orbit Jun 02 '15 at 17:58
  • @LightnessRacesinOrbit If I do this: `Singleton inst = Singleton::getInstance(); inst->foo();` - http://coliru.stacked-crooked.com/a/5b15aa04bb2a1ec6 - How can destructor be called twice if constructor was called only once? Why there is no Seg Fault? – vladon Jun 02 '15 at 18:07
  • @vladon: The constructor was called once and then the copy constructor was called once. Two objects (one a temporary). http://coliru.stacked-crooked.com/a/e336e06b637aad82 – Lightness Races in Orbit Dec 14 '15 at 15:54
2

@LightnessRacesInOrbit answer is correct and to the point. Since your question is somehow dedicated to best practices when implementing a Singleton (which you should try to avoid btw), I'll give you my take on it. You can use something called the Curiously Recurring Template Pattern to create a Singleton base class which takes as a template parameter the class you want to make a Singleton. Once you've done that correctly, creating Singletons is like a walk in the park. Just derive Foo from Singleton<Foo> and make Foo::Foo() and Foo::~Foo() private. Here is the code I use, with comments, live on Coliru:

// Singleton pattern via CRTP (curiously recurring template pattern)
// thread safe in C++11 and later

#include <iostream>
#include <type_traits>

// generic Singleton via CRTP
template <typename T>
class Singleton
{
protected:
    Singleton(const Singleton&) = delete; // to prevent CASE 3
    Singleton& operator=(const Singleton&) = delete; // to prevent CASE 4
    Singleton() noexcept = default; // to allow creation of Singleton<Foo>
    // by the derived class Foo, since otherwise the (deleted)
    // copy constructor prevents the compiler from generating
    // a default constructor;
    // declared protected to prevent CASE 5
public:
    static T& get_instance()
    noexcept(std::is_nothrow_constructible<T>::value)
    {
        static T instance;
        return instance;
    }
    // thread local instance
    static thread_local T& get_thread_local_instance()
    noexcept(std::is_nothrow_constructible<T>::value)
    {
        static T instance;
        return instance;
    }
};

// specific Singleton instance
// use const if you want a const instance returned
// make the constructor and destructor private
class Foo: public Singleton</*const*/ Foo>
{
    // so Singleton<Foo> can access the constructor and destructor of Foo
    friend class Singleton<Foo>;
    Foo() // to prevent CASE 1
    {
        std::cout << "Foo::Foo() private constructor" << std::endl;
    }
    // OK to be private, since Singleton<Foo> is a friend and can invoke it
    ~Foo() // to prevent CASE 2
    {
        std::cout << "Foo::~Foo() private destructor" << std::endl;
    }
public:
    void say_hello()
    {
        std::cout << "\t Hello from Singleton" << std::endl;
    }
};

int main()
{
    Foo& sFoo = Foo::get_instance();
    sFoo.say_hello();

    Foo& sAnotherFoo = Foo::get_instance(); // OK, get the same instance
    sAnotherFoo.say_hello();

    Foo& sYetAnotherFoo = sFoo; // still OK, get the same instance
    sYetAnotherFoo.say_hello();

    thread_local Foo& stlFoo = Foo::get_thread_local_instance(); // thread local instance
    stlFoo.say_hello();

    // CASE 1: error: 'Foo::Foo()' is private
    // Foo foo;
    // Foo* psFoo = new Foo;

    // CASE 2: error: 'Foo::~Foo()' is private
    Foo* psFoo = &Foo::get_instance(); // can get pointer
    psFoo->say_hello();
    // delete psFoo; // cannot delete it

    // CASE 3: error: use of deleted function 'Foo::Foo(const Foo&)'
    // Foo foo(sFoo);

    // CASE 4: error: use of deleted function 'Foo& Foo::operator=(const Foo&)'
    // sFoo = sAnotherFoo;

    // CASE 5: error: 'Singleton<T>::Singleton() [with T = Foo]' is protected
    // Singleton<Foo> direct_sFoo;
}
vsoftco
  • 55,410
  • 12
  • 139
  • 252
0

new Singleton() does not have a matching delete, so yea, you are leaking a resource.

You'll get memory back when the program closes, but not all resources are returned when the program ends.

You can fix it by making instance a std::auto_ptr or std::unique_ptr. Or just don't use a pointer.

QuestionC
  • 10,006
  • 4
  • 26
  • 44