Memory leak with textures


#1

I have a memory issue, it seems that if I load a texture with the below function and then use SDL_DestroyTexture(texturename); followed by texturename= nullptr; to release it, the system memory used is not released. What am I doing incorrectly?

 SDL_Texture* LoadTexture(string file)
 {
 SDL_Surface *image = nullptr;
 //Load the image
 image = IMG_Load(file.c_str());

 if (!image)
 {
 cout << "Unable to load image:" << file.c_str()<< " SDL_image Error: "<< IMG_GetError() << "\n" << endl;
  image = SDL_CreateRGBSurface(0,1,1,32,0x00FF0000,0x0000FF00,0x000000FF,0xFF000000);

   SDL_FillRect(image,nullptr,SDL_MapRGB(image->format, 255,255,255));
    }
    SDL_SetColorKey(image,SDL_TRUE,SDL_MapRGB(image->format, 255,0,255));
    SDL_Texture *texture = SDL_CreateTextureFromSurface(ren, image );
    return texture;
    SDL_DestroyTexture(texture);
    texture = nullptr;
    SDL_FreeSurface(image);
    image= nullptr;
    }

#2

As written, this never frees any memory.

That block is the failure block and is a little confusing. On failure, you may prefer to return NULL so you can detect failure and respond appropriately. As it is, you instead get a dummy texture that is not even the size you expected.

This creates a new texture, then returns it, ending processing of this function. The rest that follows the return is unreachable code. The texture and surface are not freed. You do not really want to free the texture here anyhow, as the whole point of the function is to get a valid texture. If you destroy the texture, it won’t be valid any more.

Try this:

 SDL_Texture* LoadTexture(string file)
 {
     SDL_Surface *image = IMG_Load(file.c_str());

     if (!image)
     {
         cout << "Unable to load image:" << file.c_str() << " SDL_image Error: "<< IMG_GetError() << endl;
         return NULL;
     }

     SDL_SetColorKey(image, SDL_TRUE, SDL_MapRGB(image->format, 255,0,255));
     SDL_Texture *texture = SDL_CreateTextureFromSurface(ren, image );
     SDL_FreeSurface(image);
     return texture;
}

Jonny D


#3

Okay well that explains part of the problem, also the code written as a failure catch is so that the application will receive an empty texture even if the selected image is invalid.

Add: Okay memory leak is now slowed. Thank you for your help, I still need to find out where the rest of the memory is going.


#4

You’re probably doing something like SDL_Texture* pMyTexture = LoadTexture("ImageFile.png");
so it’s up to you to, at shutdown of the application, execute SDL_DestroyTexture(pMyTexture); to free the memory allocated by your LoadTexture function.


#5

Naith, that is what I am and have been doing, Everything that is created is either SDL_Destroy()'ed or SDL_Free()'ed on close. I found the secondary issue with the memory leak was no longer apparent nor detected in Dr Memory when the application is limited to 60 FPS. If I let it run unthrottled, Dr memory cites the Nvida driver as the leak. Also this utility is how I found the first leak to be in my code.