Singleton模式析构函数C++

use*_*172 7 c++ singleton valgrind destructor

我有这个单身模式,它运行正常.但是当我用valgrind执行我的程序来检查内存泄漏时,似乎实例永远不会被破坏.

我的错误在哪里?

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();
};
Run Code Online (Sandbox Code Playgroud)

的.cpp

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;
}
Run Code Online (Sandbox Code Playgroud)

它没有关系,但在初始化时,我从文件中读取了一堆单词,然后将它们保存在地图实例中.

谢谢

bam*_*s53 14

Stopwords::~Stopwords() {
    delete instance;
}
Run Code Online (Sandbox Code Playgroud)

这是类的实例的析构函数.你可能打算在程序结束时调用这个函数,好像它是一种"静态"析构函数,但这不是它的意思.

所以你的析构函数的析构函数会启动对Stopwords实例的破坏; 你在这里有一个无限循环,你永远不会进入.如果你进入这个循环,那么程序可能会崩溃.

有一种更简单的方法来做单例:不要将实例保持为手动分配的静态类成员,而只需将其保存为静态函数变量.C++将为您管理创建和销毁它.

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;
};
Run Code Online (Sandbox Code Playgroud)

此外,您应该将不需要修改类的成员函数标记为const:

std::map<std::string,short> getMap() const;
Run Code Online (Sandbox Code Playgroud)


Arn*_*rtz 11

问题是你永远不会手动调用析构函数或删除实例指针,即从类外部调用.因此析构函数中的删除将永远不会被执行,这意味着析构函数永远不会被执行,这意味着删除永远不会被执行,这意味着......你看到你在那里做了什么?你的析构函数间接地称自己为自己不顺利.而且你永远不会从外面打电话,所以它永远不会被召唤 - 幸运的是.

你应该改变你的单身实现,也许是Meyers单身(查找),或者甚至更好地不使用单身.在像这样的情况下,如果它们是数据源,那么处理模式的弱点就太多了.

  • 他也可以使用std :: unique_ptr <Stopwords>而不是原始指针. (2认同)

The*_*777 -7

在你的析构函数中你做:

Stopwords::~Stopwords() {
    delete instance;
}
Run Code Online (Sandbox Code Playgroud)

我建议你添加:

Stopwords::~Stopwords() {
    delete instance;
    instance = 0;
}
Run Code Online (Sandbox Code Playgroud)

此调用确保指针不仅从内存中删除,而且不指向任何内容。删除指针时,您需要确保它不再指向任何内容,否则确实可能会出现内存泄漏。

  • 如果析构函数实际上不是从外部调用的,那么这不会有任何帮助。 (2认同)