I followed the advices in a previous question and solved a problem of loading a file into memory. However, I found a problem when I free the resources. If I try to free the TTF_Font
file before freeing the structure which holds it, the program crashes.
I believe it occurs because double Free()
. Free()
twice results undefined behaviour.
Accordingly to the documentation, TTF_CloseFont
frees BOTH font pointer and the font itself. I suspected that when this occurs, the SDL_RWclose
would free an already freed pointer, so it crashes. But when SDL_RWclose
frees one of the resources freed by TTF_CloseFont
, the font itself, it does not occurs. Another indication to me of undefined behaviour
More info: the order which the ptr_mem_buff
(where the font is stored) is freed does not affect the crash (in my environment).
Also, set the pointers to nullptr
should have solved, as free(nullptr)
results nothing. But the program still crashes even after setting the ptr_Font
to null after TTF_CloseFont(ptr_Font);
How should I correctly free these resources?
Code snippet:
ptr_str_rwops = SDL_RWFromFile("IMG/FreeMono.ttf", "rb");
var_size_of_file = SDL_RWsize(ptr_str_rwops);
ptr_mem_buff = calloc(1, var_size_of_file);
SDL_RWread(ptr_str_rwops, ptr_mem_buff, 1, var_size_of_file);
SDL_RWclose(ptr_str_rwops);
ptr_str_rwops2 = SDL_RWFromConstMem(ptr_mem_buff, var_size_of_file);
ptr_Font = TTF_OpenFontRW(ptr_str_rwops2, 1, 72);
ptr_Superficie_texto = TTF_RenderText_Solid(ptr_Font, "Hello World", str_SDL_colour);
/*CUT UNRELATED CODE*/
// Example 1: works fine (in my environment, but I suspect undefined behaviour)
SDL_RWclose(ptr_str_rwops2);
free(ptr_mem_buff);
TTF_CloseFont(ptr_Font);
// Example 2: crashes everytime, I believe exist double Free()
TTF_CloseFont(ptr_Font);
SDL_RWclose(ptr_str_rwops2);
free(ptr_mem_buff);
// Another approach:
TTF_CloseFont(ptr_Font);
ptr_Font = nullptr;
SDL_RWclose(ptr_str_rwops2); // still crashes
free(ptr_mem_buff);
This call
ptr_Font = TTF_OpenFontRW(ptr_str_rwops2, 1, 72);
tells TTF to dispose of the RWOps stream (that's what the 1 means). You don't have to close that stream because the call to TTF_CloseFont()
will do that. You DO have to free the ptr_mem_buff
though, because the RWOps stream will not do that.