Sign in to follow this  
willthiswork89

array for cleaning?

Recommended Posts

I want to clean my surfaces through an array in another file like like this.. void cleanup(SDL_Surface* surfaces[]) { for(int i = 0; i < surfaces.size(); ++i) { SDL_FreeSurface(SDL_Surface* surfaces[i]); } } would this work according to what i said or not?

Share this post


Link to post
Share on other sites
Should be very easy to determine if it works or not; try it. But assuming C or C++, no, that won't work, because pointers does not have a member function called size, or any member function.

You must provide the size of the array manually as a separate parameter. Or, if C++, use std::vector, which DOES have a size function.

Share this post


Link to post
Share on other sites
yea okay but if i do this in main

Clean_Up(2, SDL_Surface* screen,SDL_Surface* image);

it will give me a compile error that im passing too many values right?

how could i pass as many sdl surfaces as i want into that array?

Share this post


Link to post
Share on other sites
if u have some surfaces in defferent variables you can
delete each one individually or you can create an array of pointers
to you surfaces and the pass in to your function the array and the
array size(number of surfaces).

Share this post


Link to post
Share on other sites
Quote:
Original post by willthiswork89
yea okay but if i do this in main

Clean_Up(2, SDL_Surface* screen,SDL_Surface* image);

it will give me a compile error that im passing too many values right?

how could i pass as many sdl surfaces as i want into that array?


1) When *calling* a function, do not put the type names before the variables you're passing in. Remember that the calling parameters can actually be any expression; you wouldn't write "okNowDoThis(int (foo + bar))".

2) The function needs to be declared in a way that matches the way it will be used. You *can* set up functions to take a variable number of arguments (see printf() family of cstdio functions), but (a) it is not easy and (b) it is very widely considered a Bad Idea for many reasons.

3) What Xai is suggesting looks like this:

void cleanup(SDL_Surface** surfaces, int howMany) {
// do the cleanup
}

cleanup(myArrayOfSurfacePointers, sizeof(myArrayOfSurfacePointers) / sizeof(SDL_Surface*));


This is how C API functions generally handle it. It is still not ideal because (a) you have to track the arrays/pointers in parallel with their length counts, instead of having a data structure that wraps those two things together, and (b) when you pass an array of unknown length across a function, you must do so by passing a pointer, and the size information is lost - thus that sizeof() trick only works for locally declared arrays (and global static ones, but you don't have any of those, do you, hmm??? :) )

But in any case, if the surfaces you want to clean up are not already in some sort of collection, then there isn't really anything useful you can do here. Design such that they are.

4) If you have specific sets of surfaces that you want to work with, the best idea may be to wrap them up in a class (or struct in C). If in C++, you can then make use of the destructor to clean things up:


class screenImageSurfacePair {
SDL_Surface* screen;
SDL_Surface* image;
public:
screenImageSurfacePair() : screen(SDL_CreateSurface(whatever)),
image(SDL_CreateSurface(whatever)) {}

~screenImageSurfacePair() {
SDL_FreeSurface(screen);
SDL_FreeSurface(image);
}
};


In C you would handle this externally:


typedef struct screenImageSurfacePair_s {
SDL_Surface* screen;
SDL_Surface* image;
} screenImageSurfacePair;

screenImageSurfacePair create() {
screenImageSurfacePair result = { SDL_CreateSurface(whatever),
SDL_CreateSurface(whatever) };
return result;
}

// Have to pass by pointer here in order to affect the correct object.
void destroy(screenImageSurfacePair* toBeDestroyed) {
SDL_FreeSurface(toBeDestroyed->screen);
SDL_FreeSurface(toBeDestroyed->image);
}


5) Otherwise, if in C++, please please please use std::vector. It will make your life easier. I'd stake my rating on it. ;)


void cleanup(const std::vector<SDL_Surface*>& surfaces) {
// just as before. std::vector does provide .size().
}

// Create a vector of surfaces:
std::vector<SDL_Surface*> mySurfaces;
mySurfaces.push_back(SDL_CreateSurface(whatever));
SDL_Surface* screen = mySurfaces.back(); // this is a copy of the pointer that
// was just inserted. So now you have two separate pointers pointing at the
// same SDL_Surface instance.

// At cleanup time, you do *not* do anything with your 'screen' pointer, but
// instead:
cleanup(mySurfaces); // nice and simple.

Share this post


Link to post
Share on other sites
BTW - I personally only ever use the std::vector version (or really the std::deque). But I figured you (the OP) asked a question about doing it with arrays, so I'd answer the question you asked.

I highly recommend you read Zahlman's post slowly a couple of times ... and adopt as many of those ideas as helpfull to you.

a simple surface wrapper class is almost definately a good idea - and in fact many projects out there have done it for various langauges ... but it might be good practice to do it yourself once to help become a better programmer.

Once you have a surface wrapper, then you can simply use a std::deque<SdlSurface> or whatever ...

Alternatively you could create a SurfaceManager class that uses a std::deque<SDL_Surface*> and frees them all in it's destructor ... I usually do that first, then refactor to the individual wrapper class if I see any benifit in it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this