   i think i have a huge memory leek related to my sprite class
  ok so i have a sprite class i'm working on, it works really grate except for one thing, when using it it can only update 576 sprite for  478 frames before the program crashes and returns 3 (0x3). yesterday as i was toying around with rotation catching i decided to test a theory of mine that a memory overflow would occur if i took say 1024 SDL_Surfaces of 32-bitdepth and 32x32 image size and cache all 360 rotations for each. well i didn't get the iconic "blue screen of death" that i was hoping for but it did crash and return 3. today as i was doing some test to see the difference between cached rotations, and dynamically rotated SDL_sufaces, the same thing happend. i fixed this by treating one surface as a static surface, and had a second surface that was set to equal NULL after each Bliting. this fixed the problem perfectly, now i tryed the same thing with my sprite class but it's not working. i presume that my issue is a huge memory leek but i cant be sure. i would appreciate any assistance on this thank you.edit:i felt i was unclear about somthinghere is my code:  #include <windows.h>#include <cstdio>#include <string>#include <sstream>#include <ctime>#include <SDL/SDL.h>#include <SDL_image.h>#include <SDL_ttf.h>#include <SDL_rotozoom.h>#include <al.h>#include <alc.h>#include <alut.h>#include<IL/il.h>#include<IL/ilu.h>#include<IL/ilut.h>extern "C" {#include "lua.h"#include "lualib.h"#include "lauxlib.h"}int FRAMES_PER_SECOND;SDL_Surface *background = NULL;SDL_Surface *message = NULL;SDL_Surface *screen = NULL;SDL_Surface *Astroids = NULL;SDL_Surface *Backdrop3 = NULL;SDL_Surface *Backdrop2 = NULL;SDL_Surface *Backdrop1 = NULL;SDL_Surface *Background = NULL;TTF_Font *font = NULL;SDL_Event event;SDL_Color textColor = { 255, 255, 255 };FILE * ctt = fopen("CON", "w" );int i,j,k,x;int randx[600];int randy[600];using namespace std;SDL_Surface *load_image( std::string filename ) {    //The image that's loaded    SDL_Surface* loadedImage = NULL;    //The optimized surface that will be used    SDL_Surface* optimizedImage = NULL;    //Load the image    loadedImage = IMG_Load( filename.c_str() );    //If the image loaded    if ( loadedImage != NULL ) {   //Create an optimized surface   optimizedImage =   SDL_DisplayFormatAlpha( loadedImage );   //Free the old surface   SDL_FreeSurface( loadedImage );   //If the surface was optimized   if ( optimizedImage != NULL ) {  //Color key surface   }    }    //Return the optimized surface    return optimizedImage;}SDL_Surface *load_image2( std::string filename ) {    //The image that's loaded    SDL_Surface* loadedImage = NULL;    //The optimized surface that will be used    SDL_Surface* optimizedImage = NULL;    //Load the image    loadedImage = IMG_Load( filename.c_str() );    //If the image loaded    if ( loadedImage != NULL ) {   //Create an optimized surface   optimizedImage = SDL_DisplayFormat( loadedImage );   //Free the old surface   SDL_FreeSurface( loadedImage );   //If the surface was optimized   if ( optimizedImage != NULL ) {  //Color key surface  SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0xFF, 0, 0xFF ) );   }    }    //Return the optimized surface    return optimizedImage;}void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL ){    //Holds offsets    SDL_Rect offset;    //Get offsets    offset.x = x;    offset.y = y;    //Blit    SDL_BlitSurface( source, clip, destination, &offset );}class sprite { public:  int x,y,h,w;  bool alive;  SDL_Surface *Blit, *roto;  SDL_Surface* SBlit;  void  init(string file, int sx, int sy);  void rotate(int num);  void display();  void kill();};void sprite::init(string file, int sx, int sy) {    ILboolean success;    ILuint texid;    alive = true;if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION){ /* wrong DevIL version */ SDL_Quit();}    x = sx;    y = sy;    ilInit(); /* Initialization of DevIL */    ilGenImages(1, &texid); /* Generation of one image name */    ilBindImage(texid); /* Binding of image name */    success = ilLoadImage(file.c_str()); /* Loading of image "image.jpg" */    if(success) {  success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);  if(success) {w = ilGetInteger(IL_IMAGE_WIDTH);h = ilGetInteger(IL_IMAGE_HEIGHT);  } else {    SDL_Quit();  }    } else {  SDL_Quit();    }    roto = load_image(file);    Blit = roto;};void sprite::rotate(int num) {    Blit = NULL;    Blit = rotozoomSurface(roto,num,1,0);}void sprite::display() {   SBlit = Blit;   apply_surface(x,y,SBlit,screen,NULL);   Blit = NULL;}void sprite::kill() { SDL_FreeSurface(Blit); SDL_FreeSurface(roto); SDL_FreeSurface(SBlit);}int init_sdl(){    SDL_Init( SDL_INIT_VIDEO );    TTF_Init();    SDL_WM_SetCaption( "SDL test", NULL );    freopen( "CON", "w", stdout );    freopen( "con", "w", stderr );    screen = SDL_SetVideoMode(1024,1024, 32, SDL_HWSURFACE|SDL_DOUBLEBUF );    fclose( ctt );    FRAMES_PER_SECOND = 30;}bool load_files(){    Background = load_image("test.png");    Astroids = load_image("backdrop.bmp");    //If there was a problem in loading the background    return true;}void clean_up(){    //Free the surfaces    delete [] background;    SDL_FreeSurface( message );    //Close the font that was used    TTF_CloseFont( font );    //Quit SDL_ttf    TTF_Quit();    //Quit SDL    SDL_Quit();}class Timer {private:    //The clock time when the timer started    int startTicks;    //The ticks stored when the timer was paused    int pausedTicks;    //The timer status    bool paused;    bool started;public:    //Initializes variables    Timer();    //The various clock actions    void start();    void stop();    void pause();    void unpause();    //Gets the timer's time    int get_ticks();    //Checks the status of the timer    bool is_started();    bool is_paused();};Timer::Timer() {    //Initialize the variables    startTicks = 0;    pausedTicks = 0;    paused = false;    started = false;}void Timer::start() {    //Start the timer    started = true;    //Unpause the timer    paused = false;    //Get the current clock time    startTicks = SDL_GetTicks();}void Timer::stop() {    //Stop the timer    started = false;    //Unpause the timer    paused = false;}void Timer::pause() {    //If the timer is running and isn't already paused    if ( ( started == true ) && ( paused == false ) ) {   //Pause the timer   paused = true;   //Calculate the paused ticks   pausedTicks = SDL_GetTicks() - startTicks;    }}void Timer::unpause() {    //If the timer is paused    if ( paused == true ) {   //Unpause the timer   paused = false;   //Reset the starting ticks   startTicks = SDL_GetTicks() - pausedTicks;   //Reset the paused ticks   pausedTicks = 0;    }}int Timer::get_ticks() {    //If the timer is running    if ( started == true ) {   //If the timer is paused   if ( paused == true ) {  //Return the number of ticks when the timer was paused  return pausedTicks;   } else {  //Return the current time minus the start time  return SDL_GetTicks() - startTicks;   }    }    //If the timer isn't running    return 0;}bool Timer::is_started() {    return started;}bool Timer::is_paused() {    return paused;}void output(char *cout, char *Error) {    fprintf(stdout, cout, Error);    fprintf( stderr, "\n" );}void outputNum(int num) {    std::stringstream test;    test << num;    fprintf(stdout, test.str().c_str());    fprintf( stderr, "\n" );}int main_loop(){    sprite mySprites[576];    bool quit = false;    char *string;    if ( init_sdl() == false ) {  output( "could not init: \n", SDL_GetError());    }    if ( load_files() == false ) {   output("could not load all files: \n", SDL_GetError());    }    Timer fps;    k=0;    for(i=0;i<1008;i+=42) {  for(j=0;j<1008;j+=42) { mySprites[k].init("test.png",i,j); k++;  }    }    i=0;    j=0;    k=0;    while ( quit == false ) {   //Start the frame timer   fps.start();   //While there's events to handle   while ( SDL_PollEvent( &event ) ) {  //If the user has Xed out the window  if ( event.type == SDL_QUIT ) { //Quit the program quit = true;  }   }   apply_surface(0, 0, Astroids, screen, NULL);   i++;   x++;   if(i==360) {i=0;   }   outputNum(i);   for(j=0;j<576;j++) { mySprites[j].rotate(i); mySprites[j].x+=1; mySprites[j].y+=1; mySprites[j].display(); if(mySprites[j].y == 1024) {    mySprites[j].y = 0; } if( mySprites[j].x == 1024 ) {    mySprites[j].x = 0; }   }   k=0;   //Update the screen   if ( SDL_Flip( screen ) == -1 ) {  return 1;   }   //Cap the frame rate   if ( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ) {  SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );   }    }    outputNum(x);}int main( int argc, char *argv[] ){   srand (time(NULL));   init_sdl();   main_loop();   return 0;}[Edited by - ishkabible on May 27, 2010 5:25:13 PM]
void sprite::rotate(int num) {    Blit = NULL;    Blit = rotozoomSurface(roto,num,1,0);}(rendering code)for(j=0;j<576;j++) { mySprites[j].rotate(i); mySprites[j].x+=1; mySprites[j].y+=1; mySprites[j].display();...1. You will probably not be able to render these sprites in realtime in any significant game.  Sprite rotation using rotozoom is done in software (and thus very slow)2. rotozoomSurface creates an entirely new surface.  You never free it -- every time you rotate your sprite, the last surface gets lost in memory.  As written, your game leakes 576 surfaces in every loop.The solution to 1) will help you with 2).  Create some kind of initialization routine for your sprite to pre-rotate its frames, and then when you go to render it use the appropriate rotated surface.  When the sprite is destroyed, loop through all those rotated frames and free them   ;  well i think i don't want to cache any of the rotated surfaces, unless i have to because with the amount of sprites i want to be able to manage at games end at any given time is about 450 to 500. so i would like to hear solution1 first. so i guess what is it, editing SDL_rotozoom so it will free the surfaces it makes mabey. i am used to the idea of puting them all in rotations but caching all 360 rotations eats up a lot of ram, the next solution (to the takes up a lot of ram issue) is to give the init function an intrival argument so that it might only cache every 2 or 4 rotations but this sacrifices accuracy so i guess im at a loss of guidance as to witch way to go. so i guess i would like to be informed more about the difficulty, cons and pros of both are.   ;  i looked at SDL_rotozoom and it free's one of the two surfaces it creates, unfortatly i don't see a way to modify it to free the other as thats what it returns and i don't know of a way to both return and free it.   ;  450 to 500 different images, or 450 to 500 sprites?  If they share the same textures there's no reason not to pre-cache all the rotated surfaces (but not for each sprite, create some kind of texture object you can query from).  If they're all different then you're not going to be able to do that in realtime, unless 'have a cup of coffee between game frames' is realtime enough for you.I'd create some TextureLoader class which contains all loaded textures.  Then you could keep an array or vector of SDL_Surface pointers in the sprite -- possibly up to 360 for every sprite if you're so inclined.  Then when a sprite is created, have it request the texture(s) it needs from the TextureLoader.  Whenever a new texture or rotation is requested, then the TextureLoader could create it otherwise it'll return a pointer to something already created.  This way all your sprites use only a single instance of any given texture.;  no i guess real-time rotations is not enough for me based off what your saying, but this program right here was made to test just that "real-time rotation and movement of sprites". it runs at 28-30fps witch is fine to me. o and 450-500 sprites that are probably going to say 20-30 different images. Let me explain what i'm doing, me and my friends were in a Flash game development class. we pretty well maxed out flashes capability in the first semester (as far as number of active sprites). though i was uselly the first(witch i was rather proud of) to get to something new like per-pixel collision we still all got to there at a certien point. the last game i made cut per-pixel collision out and instead used radial. it still appeared to perfect as hands and feet (was top-down shooter) and heads where all circular. this gave way to particle effects like blood and limb amputation when you got shot (we also had a comption going to see who could make the most bloody game). any who we spent the whole last semester trying to improve are code to accommodate more sprites. we didn't do very well at this. so i got the idea of making a Lua interpreter that worked with OpenGL to give us extreme power. well OpenGL proved to have a steep learning curve even though i was already used to C++. so i took a short term side trip off to SDL where i hope to make version1.0 of something me and my friends could use to make more intense games. the absolute minimal is 300 sprites, this being because 200 is the best any of us could do (and that was with very simple particle effects). however i would like to achieve 400-500 as this would mean maxing out this framework would take some time. ok thats about all i got for now   ;  If the images are small enough for you to maintain 30 fps even rotating 476 surfaces, why do you need 360 degrees of precision for each of them?If you're dead-set on doing it the way you are now, then it's simply a matter of determining whether the sprite you're blitting has been rotated and freeing if it so after rendering.  But again, you could push your engine a lot harder if you were more efficient with your sprite creation and rotation.   ;  ok then i would like to be able to push it harder, so do you think i need a stranded say 36 degrees or should i add an argument to the sprite init() function so that for each individual sprite i can select the degrees by witch it skips.   ;  i tested 36 or every 10 degrees as an option and it is unacceptable, i'm going to toy around with 60 and some others maybe 90, 180 you get the picture. but any suggestion would be nice.   ;  ok so 90 seems to acceptable as far as rotations are concerned but given that my sprite buffer is going to be capable of 600 sprites just that means that just a simple game would take up 1.6g of mem, that is unaceptable. i think i am going to make a spite type class so that for all 600 sprites could just call on 20-30 different (user defined via Lua) types for there display info, well the problem is fixed for now so thanks for giving me some incite and ideas to improve my engine. i especially think your idea of just having 20-30 images to call on vs. one for each sprite should improve efficacy a lot. thanks   