c ++中单例类中的内存泄漏

时间:2013-10-27 05:32:54

标签: c++ singleton

我有一个单身课程。我正在创建它的对象。使用它。一旦它超出范围,将调用析构函数。

再次创建一个新对象,因为instanceFlag为false,它将再次分配新内存。

#include <iostream>

using namespace std;

class Singleton
{
private:
    static bool instanceFlag;
    static Singleton *single;
    Singleton()
    {
        //private constructor
    }
public:
    static Singleton* getInstance()
    {
        if(! instanceFlag)
        {
            single = new Singleton();
            instanceFlag = true;
            return single;
        }
        else
        {
            return single;
        }
    }
    void method()
    {
        cout << "Method of the singleton class" << endl;
    }
    ~Singleton()
    {
        instanceFlag = false;
    }
};

bool Singleton::instanceFlag = false;
Singleton* Singleton::single = NULL;



int main()
{
    Singleton *sc1,*sc2;
    {
        sc1 = Singleton::getInstance();
        sc1->method();
        delete sc1;
    }
    sc2 = Singleton::getInstance();
    sc2->method();

    return 0;
}

我怀疑旧记忆会发生什么?我认为它是一个内存泄漏。如果是,如何解决给定代码中的这个问题?

任何评论都有助于理解内部。

5 个答案:

答案 0 :(得分:2)

指针是包含内存中某个地址的变量。与任何其他变量一样,指针可能超出范围,但这与它指向的信息无关。这就是泄漏的发生方式。

{
    char* p = new char[128];
}

p超出范围时,分配的地址会消失,但分配不会受到影响;它仍然被分配,其内容不受影响,只不过丢弃一个信封会影响到它的房子。

要解决这个问题,您需要具有引用计数的内容,例如std::shared_ptr / std::weak_ptr或RAII容器(如std::unique_ptr等)。具有析构函数的内容超出范围

最好用引用来实现Singleton模式。

class Singleton {
    Singleton() {
        // constructor code...
    }
    static Singleton s_singleton;
public:
    static Singleton& GetSingleton() {
        return s_singleton;
    }
};

class Singleton {
    Singleton() = delete; // if you don't have a ctor, lets not have one at all.
public:
    static Singleton& GetSingleton() {
        static singleton;
        return singleton;
    }
};

答案 1 :(得分:0)

我使用易于使用的valgrind,它用于检测内存泄漏。 http://valgrind.org/docs/manual/quick-start.html

请参阅headfirst c教程以检测内存泄漏。

答案 2 :(得分:0)

sc1sc2是指针,它们不是Singleton个对象。当Singleton::~Singleton()超出范围时,没有电话。

你的问题出在其他地方。删除sc1后,您未将Singleton::instanceFlag设置为false。这意味着sc2->method()取消引用指向已删除对象的指针。

您应该将析构函数设为私有,并引入一个新的成员函数来删除该对象。此外,您真的不需要Singleton::instanceFlag。只需检查Singleton::single == NULL即可。删除时,再次将其设置为NULL。

答案 3 :(得分:0)

首先,您实现单例模式的方式是错误的,

if(! instanceFlag)
{
    single = new Singleton();
    instanceFlag = true;
    return single;
}
else
{
    return single;
}

单例模式的整个要点不是具有该类的多个实例,而是只有一个。使用上面的标志不是一个好的实现,您没有将标志设置为true,因此重新分配了singleton类,这确实违反了singleton模式的规则

您可以使用类似以下的内容

================================================ ===========

public:
    static Singleton* getInstance()
    {
        if(! single )//check if class is already instantiated once (allocation already 
          //done)
        {
            single = new Singleton();
            instanceFlag = true;
        }
            return single;
    }

或者您也可以使用非指针

public:
    static Singleton& getInstance()
    {
        static Singleton single
        return single;
    }

答案 4 :(得分:-2)

不应删除单身人士。

您的问题是already answered