Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to free static member variable in C++?

Can anybody explain how to free memory of a static member Variable? In my understanding it can only be freed if all the instances of the class are destroyed. I am a little bit helpless at this point...

Some Code to explain it:

class ball
{
    private:
    static SDL_Surface *ball_image;
};
//FIXME: how to free static Variable?
SDL_Surface* ball::ball_image = SDL_LoadBMP("ball.bmp");
like image 458
user299831 Avatar asked May 04 '10 23:05

user299831


3 Answers

The pointer itself will be around until the program shuts down. However, what it points to is fair game. You can free that at any time.

If what you're worried about is memory leaks, then you have a few options that I see:

  1. Just let it leak. All the memory from the program will be released when it shuts down. However, if you need more than just the memory being freed (like you want a destructor to run), then that's not such a good idea.

  2. Have a static member variable which keeps track of how many instances of the class have been created. Free the memory when it reaches zero and reallocate it if it goes above 0 again.

  3. Have a function of some kind which runs when the program is shutting down and have it worry about freeing the memory.

  4. If you can, make it so that it's not a pointer anymore. If it's not a pointer, you don't have to worry about it.

  5. Use a smart pointer or auto_ptr. That way, when the pointer itself is destroyed, the memory will be taken care of.

Personally, I'd advise 4 if you can and 5 if you can't, but you have several options.

like image 72
Jonathan M Davis Avatar answered Oct 26 '22 18:10

Jonathan M Davis


From the sound of it, you don't really want a pointer at all. In fact, since this is coming from a factory function in a C library, it isn't really a "first-class" C++ pointer. For example, you can't safely delete it.

The real problem (if there is one) is to call SDL_FreeSurface on it before the program exits.

This requires a simple wrapper class.

struct smart_sdl_surface {
    SDL_Surface *handle;

    explicit smart_sdl_surface( char const *name )
        : handle( SDL_LoadBMP( name ) ) {}
    ~smart_sdl_surface()
        { SDL_FreeSurface( handle ); }
};

class ball
{
    private:
    static smart_sdl_surface ball_image_wrapper;
    static SDL_Surface *& ball_image; // reference to the ptr inside wrapper
};
smart_sdl_surface ball::ball_image_wrapper( "ball.bmp" );
SDL_Surface *&ball::ball_image = ball::ball_image_wrapper.handle;

When the program initializes, the constructor is called and the file is read. When the program exits, the destructor is called and the object is destroyed.

like image 35
Potatoswatter Avatar answered Oct 26 '22 17:10

Potatoswatter


The static member variable in this case is a pointer. You can't free it, but you can free what it points to:

SDL_FreeSurface(ball_image);

You might then want to set ball_image to 0, to record the fact that you no longer have an image.

it can only be freed if all the instances of the class are destroyed

If by "the class" you mean ball, then no. Static members of ball continue to exist regardless of how many instances of ball there are. The only way a static member might be destroyed before program exit is if you do some (implementation-dependent) thing like unloading the dll which contains the class. But in this case the static member is just a pointer, so (1) destroying it will just destroy the pointer, not the pointee, and (2) there is no need to destroy a pointer anyway, it doesn't occupy significant resources.

like image 41
Steve Jessop Avatar answered Oct 26 '22 19:10

Steve Jessop