i have this singleton pattern and it runs ok. But when i execute my program with valgrind to check memory leaks, it seems that the instance is never destroyed.
Where is my mistake?
class Stopwords {
private:
static Stopwords* instance;
std::map<std::string,short> diccionario;
private:
Stopwords();
public:
~Stopwords();
public:
static Stopwords* getInstance();
std::map<std::string,short> getMap();
};
Stopwords* Stopwords::instance = NULL;
Stopwords::Stopwords() {
diccionario = map<string,short>();
char nombre_archivo[] = "stopwords/stopwords.txt";
ifstream archivo;
archivo.open(nombre_archivo);
string stopword;
while(getline(archivo,stopword,',')) {
diccionario[stopword] = 1;
}
archivo.close();
}
Stopwords::~Stopwords() {
delete instance;
}
Stopwords* Stopwords::getInstance() {
if (instance == NULL) {
instance = new Stopwords ();
}
return instance;
}
map<string,short> Stopwords::getMap(){
return diccionario;
}
It's not relevant but in the initialization, i read a bunch of words from a file and i save them in a map instance.
Thanks
No, and in general objects in C++ are not given private destructors. Keep in mind that Singleton means that there is only one instance, and so it is construction, not destruction, that needs to be controlled / prevented.
Longer answer: You cannot destroy a singleton, except you use a special Classloader. If you need to destroy it, you shouldn't use a singleton at all.
And deletion of singleton class object would be allow only when the count is zero. To design C++ delete singleton instance, first, we need to make the singleton class destructor private, so, it can not be accessed from outside of the class. Hence, user cannot delete the singleton instance using the keyword “delete”.
Second, developers may inadvertently reference objects from Singletons. These referenced objects would normally be garbage collected, but because Singletons stay in memory for as long as the program is running, they will keep these "other" objects in memory as well, causing a memory leak.
The problem is that you never call the destructor or delete on the instance pointer by hand, i.e. from outside the class. So the delete inside the destructor will never get executed, meaning the destructor will never get executed, meaning the delete will never get executed, meaning... You see what you did there? Your destructor is indirectly calling itself which will not go well. And you never call it from the outside, so it never gets called at all - luckily.
You should change your singleton implementation, maybe a Meyers singleton (look it up), or even better not use a singleton at all. In cases like this one, where they are data sources, there are just too much weaknesses of the pattern to deal with.
Stopwords::~Stopwords() {
delete instance;
}
This is the destructor for instances of the class. You probably intended this function to be called when the program ends, as though it were a kind of 'static' destructor, but that's not what this is.
So your destructor for instances of Stopwords initiates destruction of Stopwords instances; You've got an infinite loop here, which you never enter. If you do get into this loop then the program will probably just crash.
There's a simpler way to do singletons: Instead of keeping the instances as a static class member that you allocate manually, simply keep it as a static function variable. C++ will manage creating and destroying it for you.
class Stopwords {
public:
static Stopwords &getInstance() {
static Stopwords instance;
return instance;
}
~Stopwords();
std::map<std::string,short> getMap();
private:
Stopwords();
std::map<std::string,short> diccionario;
};
Also, you should mark member functions that don't need to modify the class as const
:
std::map<std::string,short> getMap() const;
So the conclusion is that your instance is never killed.
Usually, when you use singleton you don't care to kill it before the program finishes. Why do you need this?
If you don't you better use static
keyword to make explicit the fact that it is alive until the program finishes.
static Singleton& getInstance()
{
static Singleton s;
return s;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With