繁体   English   中英

C++ 释放静态变量

[英]C++ freeing static variables

我希望我的班级有一个指向动态分配的内存区域的静态指针。 我了解如何初始化它 - 就我而言,我将在第一个对象需要它时对其进行初始化。 但是,我不知道在代码中何时/何地释放它。 我想在程序终止时释放它。

我可能能够在对象的析构函数中释放指针,但随后我必须维护一个对象计数,以查看当对象是最后一个正在使用的对象时释放是否安全。

有没有更优雅的方法来做到这一点?

请告诉我。

谢谢,jbu

您在这里有两种解决方案:

  1. 不要删除删除它(你在 C++ 中,你使用 new 和 delete,对吧?;))。 今天几乎所有的操作系​​统都会在应用程序完成后“释放”应用程序分配的内存。 但这不是一个好的解决方案,例如,这使得内存泄漏难以检测。
  2. 将您的指针封装到一个类中(作为成员) ,然后使用这个类作为您的静态类型。 这样,您就知道将在应用程序结束时调用类析构函数。 然后,您只需删除析构函数中的数据,工作就完成并清理了。 这就是 RAII 的力量。

我建议你做 2,这是一个非常干净的方式来做到这一点。


这是一个简单的例子。 而不是这样做

static Thing* things = new Thing(); // or whatever way to initialize, here or in a specific function

你会这样做:

class ThingManager // or whatever name you like
{
public:
   ThingManager( Thing* thing ) : m_thing( thing ) { }//or create it here? whatever solution suits your way of creating the data

   ~ThingManager() { delete m_thing; } // THAT's the important part!

    Thing* instance() const { return m_thing; } // or whatever accessor you need, if you need one

private:
    Thing* m_thing;
};

进而

static ManagedThing thing; // now i can access it via thing.instance() 

当程序结束时,静态变量(不再是指针)将被销毁,并且将调用它的析构函数来执行此操作。

它的编写只是为了让您了解如何做到这一点。

将其放入智能指针中。 它将具有静态生命周期并在main返回后被销毁:

static std::auto_ptr<T> thePointer;

另一种选择是注册您自己的atexit函数:

// static
void YourClass::freePointer(void)
{
    delete getPointer();
}

// static
T* YourClass::getPointer(void)
{
    if (!thePointer)
    {
        thePointer = new T;
        atexit(freePointer);
    }

    return thePointer;
}

这将具有相同的效果。 您已经提到的另一个选项是保留一个静态计数器。 请注意,您实际上可以非常有效地将其包装起来。

从操作系统的角度来看,在程序终止时释放内存没有任何意义,所做的只是缓慢终止。 您的应用程序眼泪就下来了你的整个地址空间终止,这将释放你在堆上分配一下子一切 在应用程序关闭时显式调用free只是在堆中混洗指针,无论如何都会被丢弃。

我们如此努力地明确释放所有内容的主要原因是确保我们不会泄漏内存并且我们的内存占用不会永远增长。

但是,如果您可以确定这是静态的,并且只有一个,并且在释放所有其他对象之前无法安全地释放它,那么在这种情况下,最好让 application终止为你照顾它。

您可以将静态变量声明为智能指针,然后在程序完成时分配的指针将被释放。

我会在类中定义一个静态计数器来跟踪对象实例计数,因为析构函数执行它会减少计数器,如果 counter== 0 也释放内存..就像你一样

当我试图让我自己的静态指针在退出时被释放时,我刚刚看到了这篇旧帖子。

正确的 C++ (C++11) 解决方案是使用智能指针,即std::unique_ptr<T>std::shared_ptr<T> ,其中 T 是您正在初始化的对象的类型。 这些模板管理对象的生命周期,并分别在对象超出范围或成为内存中的最后一个引用时删除对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM