When stepping through the following the debugger encounters a SEGFAULT during the 2nd pass of SDL_CreateTextureFromSurface
.
All I have been able to determine is that this may have something to do with pulling IMG_Load
from a member variable. When I access IMG_Load
directly instead of through a->getSurface()
or when I return IMG_Load
directly from a->getSurface()
then this error doesn't occur.
The following fails:
#include <SDL.h>
#include <SDL_image.h>
class Foo
{
SDL_Surface* _surface;
public:
SDL_Surface* getSurface()
{
return _surface;
}
void setSurface(SDL_Surface* surface)
{
_surface = surface;
}
};
int main()
{
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_PNG);
SDL_Window* window = SDL_CreateWindow("foo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
Foo* foo = new Foo();
foo->setSurface(IMG_Load("img.png"));
bool quit = false;
SDL_Event e;
while(!quit)
{
SDL_SetRenderDrawColor(renderer,100,0,0,0);
SDL_RenderClear(renderer);
SDL_Surface* surface = foo->getSurface();
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_RenderPresent(renderer);
SDL_UpdateWindowSurface(window);
while(SDL_PollEvent( &e ) != 0)
{
if (e.type == SDL_QUIT)
{
quit = true;
}
}
}
delete foo;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
return 0;
}
Changing Foo
as follows evades the error:
class Foo
{
public:
SDL_Surface* getSurface()
{
return IMG_Load("img.png");
}
};
and the following succeeds as well:
SDL_SetRenderDrawColor(renderer,100,0,0,0);
SDL_RenderClear(renderer);
SDL_Surface* surface = IMG_Load("img.png");
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_RenderPresent(renderer);
SDL_UpdateWindowSurface(window);
At the end of first iteration you invoke SDL_FreeSurface(surface);
making SDL_Surface* _surface;
pointer stored in Foo
class instance invalid as well. So on the next iteration SDL_Surface* surface = foo->getSurface();
returns the same invalid pointer causing crash and / or other nasty things associated with Undefined Behavior.