c++design-patternsmemory-managementsingletonimplementation

How does singleton instance implementation in C++ does not leak memory?


I'm studying about singletons in design patterns and I saw this singleton implementation and I tested it with fsanitize=address, because there is no delete keyword even though there is a new keyword being use I suspect that this is an incomplete implementation and therefore has memory leak, but after running the program it doesn't seems to have one? why is that? we are allocating new memory for *singleton so it should be a dangling pointer?

class Singleton {
    public:
        static Singleton& instance() {
            static Singleton* singleton = new Singleton();
            return *singleton;
        }

        void set_data(int value) { data = value; }
        int get_data() { return data; }
    private:
        Singleton() : data(0) {}
        ~Singleton() {}
        int data;    
};

How come this singleton implementation does not leak memory in C++?

If I rewrite this singleton class into something like this:

class Singleton {
    public:
        static Singleton& instance() {
            static Singleton* singleton;
            
            if (singleton == nullptr) {
                singleton = new Singleton();
            }

            return *singleton;
        }

        void set_data(int value) { data = value; }
        int get_data() { return data; }
    private:
        Singleton() : data(0) {}
        ~Singleton() { delete this; }
        int data;    
};

What would be the difference?


Solution

  • How come this singleton implementation does not leak memory in C++?

    This singleton implementation does leak memory.

    That said, the memory is leaked immediately before the program terminates, and thus the leak doesn't really matter. This is a common technique that can be used to speed up the termination time, as well as avoid certain rare cases of Static Destruction Order Fiasco.

    I tested it with fsanitize=address

    Few points regarding this:

    • Did you run with ASAN_OPTIONS=detect_leaks=1? Address sanitizer does not do leak detection by default on all systems.
    • Sanitizers don't generally guarantee to find bugs, so your test is not a proof that there is no leak.
    • In this case, the non-detection might be intentional; but I don't know for sure.