Martijn Courteaux
Martijn Courteaux

Reputation: 68847

C++: Best way to destruct static stuff

When I have a class containing static stuff, how can I free the memory at the end of the application the best way?

Foo.h

class GLUtesselator;

class Foo
{
private:
    static GLUtesselator *tess;
public:
    Foo();
    virtual ~Foo();
}

Foo.cpp

#include "Foo.h"

#include <GL/glu.h>

GLUtesselator *Foo::tess = gluNewTess(); // System call

Foo::Foo() {}
Foo::~Foo()
{
     // And of course I don't want to destruct it here,
     // because I'm going to use the tesselator in other instances of Foo
     // Otherwise:
     // gluDeleteTess(tess);
}

Are there better alternatives to making a method to remove static stuff and call it when the app terminates?
Or can I say: "Oh, whatever, the application is terminated. The OS will free the memory..." ?

Thanks

Upvotes: 5

Views: 551

Answers (4)

Lior Kogan
Lior Kogan

Reputation: 20608

for global static variables:

CFoo* pFoo= NULL;

void DoneFoo()
{
    delete pFoo;
}

void Init()
{
    pFoo= new CFoo();
    atexit(DoneFoo);
}

or:

class CFoo
{
     ......
};

#define NewFoo(F_name)                                                             \
    CFoo* F_name##Init();                                                          \
    void  F_name##Done();                                                          \
    CFoo* F_name= F_name##Init();                                                  \
    CFoo* F_name##Init()  { CFoo* F= new CFoo(); atexit(F_name##Done); return F; } \
    void  F_name##Done()  { delete F_name; }    

NewFoo(F1);

for member static variables:

class CFoo
{
    static int* pKuku;
    static void DoneKuku() { delete pKuku;                     }
    static int* InitKuku() { atexit(DoneKuku); return new int; }
public:
};

int* CFoo::pKuku= CFoo::InitKuku();

I don't think it is a good idea to let the OS free memory automatically, because you'll have memory leaks. When you have 'legitimate' memory leaks - it will be harder to notice 'illegitimate' ones, so you should strive to having no memory leaks at all.

Upvotes: 2

Loki Astari
Loki Astari

Reputation: 264381

Simple. Don't make the static member a pointer.
Then it will be correctly constructed and destructed.

Foo.h

#include <GL/glu.h>

class Foo
{
    private:
        static GLUtesselator  tess;
    public:
                 Foo();
        virtual ~Foo();
};

Foo.cpp

// 
GLUtesselator  Foo::tess;

If you have to use the gluNewTess() and gluDeleteTess() then you can use a shared pointer. I don't have a compiler so the exact usage may not be absolutely correct. But the shared_ptr does have this ability.

Foo.h

#include <GL/glu.h>

typedef std::shared_ptr<GLUtesselator,void (*)(GLUtesselator*)> AutoGluTess;
class Foo
{
    private:
        static AutoGluTess  tess;
    public:
                 Foo();
        virtual ~Foo();
};

Foo.cpp

// 
AutoGluTess    Foo::tess(gluNewTess(), &gluDeleteTess);

Upvotes: 7

Peter Alexander
Peter Alexander

Reputation: 54270

You don't need to destroy it. All operating systems I know will correctly free the memory and release any resources held by the object on application termination (Note: the destructor will not be called automatically, but the resources will be freed).

If you really want to destroy it though, either

  1. Don't use a pointer as Martin York describes,
  2. Or (if you need a pointer), use an auto_ptr or tr1::unique_ptr so that the pointee is automatically deleted when it goes out of scope (which is at the end of the application for static variables).

Upvotes: 2

Bwmat
Bwmat

Reputation: 4578

Since it's static, there will only ever be one instance. Unless this GLUtesselator is really huge, I doubt you will ever need to free it yourself.

like you said, "Oh, whatever, the application is terminated. The OS will free the memory..."

Upvotes: 1

Related Questions