【问题标题】:Static allocated memory release静态分配的内存释放
【发布时间】:2013-08-29 17:49:46
【问题描述】:

我有一个如下的单例类:

class myClass
{
public:
    static myClass* getInstance();
    ~myClass();

private:
    static myClass* m_instance;
protected:
    myClass();
};

对于上面的类定义是:

myClass* myClass::m_instance = 0;

myClass::myClass() 
{
}

myClass::~myClass() 
{
}

myClass* myClass::getInstance() 
{
   if(m_instance == 0)
     m_instance = new myClass;
   return m_instance;
}

众所周知,一旦使用new 分配内存,就应该将其释放到堆中以防止内存泄漏。就我而言,我分配了与析构函数无关的内存,因为它是静态的。 那么,我怎样才能释放分配的内存呢?我应该完全释放它吗?这会不会导致内存泄漏,因为我还有其他类的对象也在 main() 中起作用?

PS:getInstance() 方法返回的对象存在于main() 中,直到应用程序关闭。

【问题讨论】:

  • 或者你可以注册一个函数到atexit()函数。
  • 假设您在为每个进程提供单独内存空间的操作系统上运行(即现在几乎所有现代操作系统),这种情况下的“内存泄漏”是无关紧要的,因为在 main 之后() 返回,进程分配的所有内存无论如何都会被操作系统回收。唯一可能产生影响的情况是 ~myClass() 是否需要在进程空间之外进行一些清理工作(例如,从 /tmp 中删除文件或其他内容)。假设情况并非如此,最简单的解决方案就是忽略该问题,因为它不会给您带来任何问题。

标签: c++ memory-management


【解决方案1】:

您可以使用智能指针代替原始指针,然后您就不必考虑它了 :)

如果你使用 C++11,你可以使用unique_ptr。如果您使用的编译器比使用 auto_ptr 更旧。

另外,上面的代码不是线程安全的。

【讨论】:

  • 我正在使用 Qt 我已经共享指针和其他我可以使用的智能指针。
【解决方案2】:

如果对象在程序关闭之前一直存在,则不必释放它。但是,您可能希望在关闭时释放单例所持有的资源(文件、套接字、数据库连接等);您可以使用在正常程序关闭期间调用的静态“去初始化”函数来执行此操作。

顺便说一句,你初始化单例的方式不是线程安全的。您可能想改用threadsafe singleton

【讨论】:

    【解决方案3】:

    在这种情况下,您必须使用 main 中的指针(或在超出范围之前您可以访问它的任何地方)删除您的对象。

    类似:

    int main()
    {
        myClass* inst = myClass::getInstance();
        // ... do something with it here
        delete inst;
    }
    

    尽管这通常是一种不好的做法,因为您不应该在程序中的任何地方都有新的/删除的“狂奔”。最好坚持 RAII 概念,并使用构造函数和析构函数将堆存储的内存与堆栈上的一些对象绑定。

    在这种特定情况下,您可以将 m_instance 声明为静态,而不是在“getInstance()”中使用“new mClass”。

    myClass& myClass::getInstance()
    {
        static myClass instance;
        return instance;
    }
    

    这样您根本不必释放任何内存,因为它会与您程序中的所有其他静态变量一起自动释放。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-17
      • 2011-09-06
      • 2013-11-22
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 2011-12-09
      相关资源
      最近更新 更多