0
\$\begingroup\$

When I call my tile engine function, the amount of memory my program uses begins to spike at about 80 - 90 megabytes per second. The memory use continues to go up until the program crashes. The function is below.

After tinkering with it, I figured out that I could reduce this bricking to about 15 megabytes per second if I called SDL_FreeSurface every time I ran the function. But this confused me, because I thought that you are only supposed to use SDL_FreeSurface when the program exits so that the images don't continue to occupy the memory.

  1. if I don't call SDL_FreeSurface before I blit the tiles, do the previously blitted tiles continue to exist?
  2. If I don't how do I fix the aforementioned bug?

The edit I made to bring the memory bricking down to 15 megabytes per second is commented out.

SDL_Surface* loadedTile = NULL;
SDL_Surface* modelIMAGE = NULL;

void enviroment::blitTiles(SDL_Surface* windowENVIRO, int tileAmount, int tileType[], int tileXenviro, int tileYenviro, bool quitTiles)
{
    HDcounter = -1;

//if(loadedTile != NULL)
//{
//    SDL_FreeSurface(loadedTile); 
//}


loadedTile = IBFobjectENVIRO.loadIMG("tileClipSheet.png");

        for(int tiles = 0; tiles < tileAmount; tiles++)
        {

            switch(tileType[tiles])
            {
                //Black square (unpassable)
                case 1: IBFobjectENVIRO.blitIMG(tileXenviro - 75, tileYenviro, windowENVIRO, loadedTile, 0, 0, 75, 75);

                        HDcounter += 1;

                        forbiddenX[HDcounter] = tileXenviro - 75;
                        forbiddenY[HDcounter] = tileYenviro;
                        forbiddenSpriteWidth[HDcounter] = 75;
                        forbiddenSpriteHeight[HDcounter] = 75;
                        forbiddenSpriteDepth[HDcounter] = 75;
                break;

                //Grey square
                case 2: IBFobjectENVIRO.blitIMG(tileXenviro - 75, tileYenviro, windowENVIRO, loadedTile, 75, 0, 75, 75);
                break;

                //Brown square
                case 3: IBFobjectENVIRO.blitIMG(tileXenviro - 75, tileYenviro, windowENVIRO, loadedTile, 150, 0, 75, 75);
                break;

                //Invisible square (unpassable)
                case 4: IBFobjectENVIRO.blitIMG(tileXenviro - 75, tileYenviro, windowENVIRO, loadedTile, 225, 0, 75, 75);

                        HDcounter += 1;

                        forbiddenX[HDcounter] = tileXenviro - 75;
                        forbiddenY[HDcounter] = tileYenviro;
                        forbiddenSpriteWidth[HDcounter] = 75;
                        forbiddenSpriteHeight[HDcounter] = 75;
                        forbiddenSpriteDepth[HDcounter] = 75;
                break;
            }

            tileXenviro += 75;

            if(tileXenviro >= level1ObjectENVIRO.level1Width)
            {
                tileYenviro += 75;
                tileXenviro = tileXenviro - level1ObjectENVIRO.level1Width;
            }
        }

    if(quitTiles == true)
    {
        SDL_FreeSurface(loadedTile);
    }
}
\$\endgroup\$
2
\$\begingroup\$

If loadIMG() is reading the image data from a file, that data needs to be stored somewhere. That somewhere is newly-allocated memory. So each time you call blitTiles() (presumably 60 times a second), you are allocating new memory that is never freed. This is why the memory usage is ballooning.

To solve this, you ought to keep your storage and loading outside of blitTiles(). loadedTile is already global, which is one storage option. Now move the image loading to somewhere before your main loop runs and then you can free it just once when your app is exiting.

\$\endgroup\$
  • \$\begingroup\$ What if I do something like sdl_surface1 = sdl_surface2;? Would I have to free sdl_surface1 before I did this? \$\endgroup\$ – TheBlackSword Nov 16 '14 at 8:11
  • \$\begingroup\$ Yes. Assignment like that is just assigning pointers (in other words, handles), and not affecting the actual memory for the surface. If you do free the surface properly, also make sure that you don't use the old pointer anywhere else. \$\endgroup\$ – Jonny D Nov 16 '14 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.