Should Singleton objects that don\'t use instance/reference counters be considered memory leaks in C++?
Without a counter that calls for explicit deletion of the singlet
A singleton would be one instance of your object. This is why it does not require a counter. If it's going to exist for the length of your application then the default destructor will be fine. The memory will be, in any case, reclaimed by the operating system when the process ends.
Any heap memory allocated by your process and not freed (deleted) will be reclaimed by the OS. If you're using the most common implementation of the singleton, which uses static variables, this would be cleaned up upon your application's termination as well.
*This does not mean that you should go around new-ing pointers and never cleaning them up though.
It's folklore to free global memory allocations explicitly before the application terminates. I suppose most of us do it out of habit and because we feel it's sort of bad to "forget" about a structure. In the C world it's a law of symmetry that any allocation must have a deallocation somewhere. C++ programmers think differently if they know and practice RAII.
In the good old days of e.g. AmigaOS there were REAL memory leaks. When you forgot to deallocate memory, it would NEVER become accessible again until the system was reset.
I don't know of any self-respecting desktop operating system these days that would allow memory leaks to creep out of an application's virtual address space. Your mileage may vary on embedded devices when there is no extensive memory bookkeeping.
Depends on your definition of a leak. Unbound memory increase is a leak in my book, a singleton isn't unbound. If you don't provide reference counting, you intentionally keep the instance alive. Not an accident, not a leak.
Your singleton wrapper's destructor should delete the instance, it is not automatic. If it just allocates memory and no OS resources, there's no point.
You can rely on it being cleaned up by the operating system.
That said, if you are in a garbage collected language with finalizers rather than destructors you may want to have a graceful shutdown procedure that can cleanly shutdown your singletons directly so they can free any critical resources in case there are using system resources that won't be correctly cleaned up by merely ending the application. This is because finalizers run on a sort of 'best effort' basis in most languages. On the other hand there a very very few resources that need this sort of reliability. file handles, memory, etc. all go back to the OS cleanly regardless.
If you are using a singleton that is lazily allocated (i.e. with a triple-check lock idiom) in a language like c++ with real destructors rather than finalizers, then you cannot rely on its destructor being invoked during program shutdown. If you are using a single static instance then the destructor will run after main completes at some point.
Regardless, when the process ends, all memory returns to the operating system.
I ran into an issue like this and I think this should work even if the main thread exits first and takes the static objects with it. Instead of this:
Singleton &get_singleton() {
static Singleton singleton;
return singleton;
}
I'm thinking
Singleton &get_singleton() {
static std::shared_ptr<Singleton> singleton = std::make_shared<Singleton>();
static thread_local std::shared_ptr<Singleton> local = singleton;
return *local;
}
so when the main thread exits and takes singleton
with it, each thread still has its own local
shared_ptr
that keeps the one Singleton
alive.