开发者

Is deleting an array stored as static local variable needed, and how?

I have a few arrays and a resource that needs deletion, the value of these variables are retained throughout the lifetime of the program and they are only used in a single f开发者_运维技巧unction so it naturally fits into static variables:

void func() {
    static GLfloat arrs[4] = {1, 1, 1, 1};
    static GLUquadric* quad = gluNewQuadric(); // delete with gluDeleteQuadric(quad)
    //... other codes ... 
}

However, if I used static, I would have trouble with delete-ing these resources since I cannot access these variables from outside the function. I can make these globals, but I would like to avoid that if possible.

So the question is:

  1. Is arrs[] stack- or heap-allocated? And so, would I need to delete it?
  2. In the case of GLUquadric, obviously the compiler would not know how to properly delete it, for now I've used a RAII wrapper class which worked beautifully, but I'm looking if there's an even simpler approach.

valgrind complained for not releasing the GLUquadric, and I guess I'd just clean it up rather than silencing valgrind even though the program should be about to end anyway when I will release them and these resources are probably(?) released when the program ends.


  1. No need to delete arrs[], it's not been allocated on the heap. It is not on the stack either, it's in the data segment somewhere, and part of your static program data and will go away when the process does.

  2. On the heap but generally not to worry about. This sort of allocating heap during static initialisation is not very good, but it only bytes you if you need any destructor calls in the end (to get rid of external resources etc.).

Edited: I'd still worry about that heap object. especially if it comes from some library; you never know what it is up to internally, it may have locked up some hardware resources or similar. You can't do anything here with smart pointers etc., but if you really need this to be allocated this way, it may be worth registering the deallocation with the atexit() function or similar. Or put the whole thing into a global static singleton object with a destructor. You only have nothing to worry about if you know that the object only contains data, i.e. don't worry about your heap.


By your description, I am assuming that these statics are declared inside of the function that uses them. In that case, you don't need to delete them. In fact, you couldn't delete them if you wanted to. Since the function wouldn't work properly if the static data wasn't available, you can't delete it. They are not stack variables since they outlive the lifetime of the function.


Use an auto ptr:

int myFunc()
{
    static GLfloat                   arrs[4] = {1, 1, 1, 1};
    static std::auto_ptr<GLUquadric> quad    = gluNewQuadric();

    // Do Stuff
}

The static variable is initialised on first use.
Then it is destroyed when the application is terminated. Because it is a smart pointer it will delete the pointer.

1: Is arrs[] stack- or heap-allocated? And so, would I need to delete it?

Neither.
And no you don;t need to delete it.
It has static storage duration, this just means that it will live until after main exits then be destroyed with the other static storage duration objects (in reverse order of creation).

2: In the case of GLUquadric, obviously the compiler would not know how to properly delete it, for now I've used a RAII wrapper class which worked beautifully, but I'm looking if there's an even simpler approach.

No. Just use a standard one to make it as simple as possible.


As your "delete" function is a simple single parameter function you can use it directly with a TR1 (or boost) shared_ptr with a custom deleter.

void func()
{
    static std::tr1::shared_ptr<GLUQuadric> quad(gluNewQuadric(), gluDeleteQuadric);
    // ...
}


The basic rule is that we should delete only whatever we allocated. If we allocated with new, release the memory with delete. If we allocated with new[], release the memory with delete[].

So for

Q1. No, don't delete. We never new'ed it

Q2. Yes, we need to delete assuming the function allocated it. However the problem is that by looking at Quadratic it is tough to know if the returned pointer is newed for only one 'Quadtric' or an 'array of Quadtric', or is it just a pointer to some static variable somewhere. So use delete or delete[] accordingly if you allocated memory dynamically.


Q1 and Q2: don't do it!. You cannot use std::auto_ptr<GLUquadricObj> since it is a resource which needs to be deallocated by a specialized deleter gluDeleteQuadric. Generally, in a state driven engine like OpenGL and GLU don't use statics - well don't use them ever, but in OpenGL context, that's especially dangerous.

Now again, seriously:

Q1. don't do it. There is no gain at all in storing a static 4-element array of integers. Define it locally where you need it. My advice: don't use c-style arrays, instead say:

const std::array<int, 4> tArray = {1, 1, 1, 1};

Q2. RAII advice given above is good, but you need a RAII wrapper which supports custom deleters:

std::shared_ptr<GLUquadricObj> 
 tMyQuadric(glCreateQuadric(), glDeleteQuadric);

Now use it at will, it will be closed and destroyed automatically, when they go out of scope and the program has no reference to it. Oh, I see the custom RAII wrapper above would also work, but please: do yourself and your followers and co-workers a favour: use standard library constructs.


As for the curious and future reference, this is my RAII template:

template <typename T, T* constructor(), void destructor(T*)>
class Managed {
    private:
        T* value;
    public:
        Managed() {
            value = constructor();
        }
        ~Managed() {
            destructor(value);
        }
        T* operator*() {
            return value;
        }
};

and it is used like this:

typedef Managed<GLUquadric, gluNewQuadric, gluDeleteQuadric> MGLUquadric;
static MGLUquadric quad = MGLUquadric();
gluSphere(*quad, 3.0f, 20, 20);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜