我有一些数组和需要删除的资源,这些变量的值在程序的整个生命周期中都保留,它们只在一个函数中使用,所以它自然适合静态变量:
void func() {
static GLfloat arrs[4] = {1, 1, 1, 1};
static GLUquadric* quad = gluNewQuadric(); // delete with gluDeleteQuadric(quad)
//... other codes ...
}
但是,如果我使用静态,我将无法删除这些资源,因为我无法从函数外部访问这些变量。我可以制作这些全局变量,但如果可能的话我想避免这种情况。
所以问题是:
答案 0 :(得分:2)
无需删除arrs [],它未在堆上分配。它不在堆栈中,它位于某个地方的数据段中,也是静态程序数据的一部分,并且在进程执行时会消失。
在堆上但一般不用担心。这种在静态初始化期间分配堆的效果并不是很好,但是如果最终需要任何析构函数调用(除去外部资源等),它只会出现字节。
已编辑:我仍然担心该堆对象。特别是如果它来自一些图书馆;你永远不知道内部是什么,它可能已经锁定了一些硬件资源或类似的东西。你不能在这里用智能指针等做任何事情,但如果你真的需要这样分配,可能值得用atexit()函数或类似的方法注册释放。或者将整个事物放入带有析构函数的全局静态单例对象中。如果你知道对象只包含数据,你就不用担心了,即不要担心你的堆。
答案 1 :(得分:1)
根据你的描述,我假设这些静态声明是在使用它们的函数内部声明的。在这种情况下,您不需要删除它们。事实上,如果你愿意,你不能删除它们。如果静态数据不可用,函数将无法正常工作,则无法将其删除。它们不是堆栈变量,因为它们比函数的生命周期更长。
答案 2 :(得分:1)
使用自动ptr:
int myFunc()
{
static GLfloat arrs[4] = {1, 1, 1, 1};
static std::auto_ptr<GLUquadric> quad = gluNewQuadric();
// Do Stuff
}
静态变量在首次使用时初始化 然后在应用程序终止时销毁它。因为它是一个智能指针,它将删除指针。
1:arrs []是堆栈还是堆分配?那么,我需要删除吗?
都不是。
不,你不需要删除它
它具有静态存储持续时间,这意味着它将一直存在,直到主要出口然后被其他静态存储持续时间对象销毁(按照创建的相反顺序)。
2:对于GLUquadric,显然编译器不知道如何正确删除它,现在我已经使用了一个非常漂亮的RAII包装器类,但我在寻找是否有更简单的方法。 / p>
没有。只需使用标准版即可使其尽可能简单。
答案 3 :(得分:1)
由于您的“删除”功能是一个简单的单一参数功能,您可以直接将TR1(或加速)shared_ptr
与自定义删除器一起使用。
void func()
{
static std::tr1::shared_ptr<GLUQuadric> quad(gluNewQuadric(), gluDeleteQuadric);
// ...
}
答案 4 :(得分:0)
基本规则是我们应该只删除我们分配的内容。如果我们使用new
分配,请使用delete
释放内存。如果我们使用new[]
分配,请使用delete[]
释放内存。
所以
Q1。不,不要删除。我们从来没有新过它
Q2。是的,我们需要删除假设函数分配它。然而问题是,通过查看Quadratic,很难知道返回的指针是仅针对一个'Quadtric'还是'Quadtric'数组新建的,或者它只是指向某个静态变量的指针。因此,如果您动态分配了内存,请相应地使用delete
或delete[]
。
答案 5 :(得分:0)
至于好奇和未来的参考,这是我的RAII模板:
template <typename T, T* constructor(), void destructor(T*)>
class Managed {
private:
T* value;
public:
Managed() {
value = constructor();
}
~Managed() {
destructor(value);
}
T* operator*() {
return value;
}
};
它的用法如下:
typedef Managed<GLUquadric, gluNewQuadric, gluDeleteQuadric> MGLUquadric;
static MGLUquadric quad = MGLUquadric();
gluSphere(*quad, 3.0f, 20, 20);
答案 6 :(得分:0)
Q1和Q2:不要这样做!。您不能使用std::auto_ptr<GLUquadricObj>
,因为它是需要由专门的删除器gluDeleteQuadric
释放的资源。通常,在像OpenGL和GLU这样的状态驱动引擎中不使用静态 - 不要使用它们,但在OpenGL环境中,这是特别危险的。
再次,严肃地说:
Q1。不要这样做。存储静态4元素整数数组时根本没有任何增益。在您需要的地方定义它。我的建议:不要使用c风格的数组,而是说:
const std::array<int, 4> tArray = {1, 1, 1, 1};
Q2。上面给出的RAII建议很好,但是你需要一个支持自定义删除器的RAII包装器:
std::shared_ptr<GLUquadricObj>
tMyQuadric(glCreateQuadric(), glDeleteQuadric);
现在随意使用它,当它们超出范围并且程序没有引用它时,它将被自动关闭和销毁。哦,我看到上面的自定义RAII包装器也可以工作,但请:自己和你的追随者和同事一个忙:使用标准的库构造。