27

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

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

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

请告诉我。

谢谢,jbu

4

6 回答 6

21

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

  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() 

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

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

于 2010-03-11T23:31:52.070 回答
16

将其放入智能指针中。它将具有静态生命周期并在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;
}

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

于 2010-03-11T23:39:23.037 回答
7

从操作系统的角度来看,在程序终止时释放内存没有真正意义,所做的只是减慢终止速度。应用程序的终止会破坏您的整个地址空间,它将一次性释放您在堆上分配的所有内容。显式调用free应用程序关闭只是对堆中的指针进行洗牌,无论如何都会被丢弃。

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

但是,如果您可以确定这是静态的,只有一个,并且在所有其他对象都被释放之前您不能安全地释放它,那么在这种情况下,让应用程序可能会更好终止为您处理。

于 2010-03-11T23:34:10.473 回答
2

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

于 2010-03-11T23:33:42.927 回答
0

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

于 2010-03-11T23:34:09.093 回答
0

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

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

于 2021-01-07T23:40:11.460 回答