Reputation: 665
My instructor says we don't need to delete a singleton object created in the heap because when out of scope its memory is released and auto deletes.
Is it that the compiler treats static objects differently that we don't need to worry about deleting this object from the heap?
In the code below, I think it's the pointer that goes out of scope in main and not the object in the heap itself, but at some point the destructor of the object should be called if indeed the memory is released for this object?
I also tried adding member function DeleteObject in main but I can't see the destructor of the object in heap being called.
but still can't see the destructor show the message on screen.
#include <iostream>
using namespace std;
class Singleton {
public:
static Singleton* GetInstance();
void Show() { cout << "Single object"; }
void DeleteObject();
~Singleton();
private:
static Singleton* psingleton;
Singleton();
};
void Singleton::DeleteObject() {
delete psingleton;
}
Singleton::~Singleton() {
cout << "\n\nAt Destructor";
}
Singleton* Singleton::psingleton = 0;
Singleton::Singleton()
{
//do stuff
}
Singleton* Singleton::GetInstance() {
if (psingleton = NULL ) {
psingleton = new Singleton();
}
return psingleton;
}
int main()
{
Singleton::GetInstance()->Show();
Singleton::GetInstance()->DeleteObject();//another try
return 0;
}
Would expect the object destructor to show a message on screen because it's called.
Upvotes: 0
Views: 379
Reputation: 36637
My instructor says we don't need to delete a singleton object created in the heap because when out of scope its memory is released and auto deletes.
Is it that the compiler treats static objects differently that we don't need to worry about deleting this object from the heap?
Your instructor is mistaken. A dynamically allocated object (e.g. created with operator new
) will only be released if it is specifically destroyed (e.g. using the corresponding operator delete
).
It does not matter if the pointer to the object is a static variable.
What does happen, with most modern operating systems, is that the operating system will reclaim memory used by a program as the program terminates (normally or abnormally). However, this does not cause a call of a destructor of a dynamically allocated object. If you rely on the destructor being called (rather than memory being reclaimed) then you need to ensure the destructor is called before the program terminates. For example, if an object manages a system resource, such as a mutex.
The C++ standard does not require dynamically allocated objects to be released as a program terminates. And most (if not all) modern operating systems (unix, windows, etc) that do reclaim memory of exiting processes reclaim memory, will not call destructors of dynamically allocated objects.
There are also operating systems that do not bother to reclaim memory of a terminating program - although usage of such systems is less common now, programs which run on them need to be specifically designed to ensure they correctly release all dynamically allocated objects.
There are, of course, techniques that can be used to ensure that dynamically allocated objects are released (e.g. store the pointer to those objects in a std::unique_ptr
). A static std::unique_ptr<T>
will be destroyed as the program terminates, and its destructor will automatically destroy any dynamically allocated object it manages. (There are, of course, ways to prevent this happening, such as by calling std::abort()
).
Upvotes: 2
Reputation: 16876
That's because you have a bug. This here
Singleton* Singleton::GetInstance() {
if (psingleton = NULL) {
psingleton = new Singleton();
}
return psingleton;
}
Doesn't ever make an object because psingleton = NULL
is always casted to false
. What you want instead is if (psingleton == NULL) {
.
With that fix, the output for me in MSVC is:
Single object
At Destructor
... which is because of the call to Singleton::GetInstance()->DeleteObject();
, not because the program has ended.
I think it's the pointer that goes out of scope in main and not the object in the heap itself, but at some point the destructor of the object should be called if indeed the memory is released for this object?
You are correct. The object on the heap does not go out of scope, and no destructor is called just from the program ending.
Upvotes: 3
Reputation: 608
I think you instructor is mistaken, the code above will cause a memory leak of Singleton objects
Upvotes: 1