Fixed bug 3790 - Memory leak with surfaces blitting on each other
authorSam Lantinga <slouken@libsdl.org>
Mon, 04 Sep 2017 11:46:14 -0700
changeset 1144852dcef74bdc5
parent 11447 f76299105635
child 11449 b7f6c4f8fbb3
Fixed bug 3790 - Memory leak with surfaces blitting on each other

bastien.bouclet

When creating two surfaces and blitting them onto the other, SDL's internal reference counting fails, and one of the surfaces is not freed when calling SDL_FreeSurface.

Example code :

SDL_Surface *s1 = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_Surface *s2 = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 32, SDL_PIXELFORMAT_ARGB8888);

SDL_BlitSurface(s1, NULL, s2, NULL);
SDL_BlitSurface(s2, NULL, s1, NULL);

SDL_FreeSurface(s2);
SDL_FreeSurface(s1);

With this example, s1 is not freed after calling SDL_FreeSurface, its refcount attribute is still positive.
src/video/SDL_surface.c
     1.1 --- a/src/video/SDL_surface.c	Sun Sep 03 17:33:49 2017 -0400
     1.2 +++ b/src/video/SDL_surface.c	Mon Sep 04 11:46:14 2017 -0700
     1.3 @@ -1193,6 +1193,10 @@
     1.4      if (surface->flags & SDL_DONTFREE) {
     1.5          return;
     1.6      }
     1.7 +    if (surface->map != NULL) {
     1.8 +        SDL_FreeBlitMap(surface->map);
     1.9 +        surface->map = NULL;
    1.10 +    }
    1.11      if (--surface->refcount > 0) {
    1.12          return;
    1.13      }
    1.14 @@ -1207,10 +1211,6 @@
    1.15          SDL_FreeFormat(surface->format);
    1.16          surface->format = NULL;
    1.17      }
    1.18 -    if (surface->map != NULL) {
    1.19 -        SDL_FreeBlitMap(surface->map);
    1.20 -        surface->map = NULL;
    1.21 -    }
    1.22      if (!(surface->flags & SDL_PREALLOC)) {
    1.23          SDL_free(surface->pixels);
    1.24      }