Я последовал советам в предыдущий вопрос и решил проблему с загрузкой файла в память. Однако я обнаружил проблему, когда освобождал ресурсы. Если я попытаюсь освободить файл TTF_Font
до освобождения структуры, которая его содержит, программа вылетит.
Я считаю, что это происходит из-за двойного Free()
. Free()
дважды приводит к неопределенному поведению.
Согласно документации, TTF_CloseFont
освобождает указатель шрифта ОБЕ и сам шрифт. Я подозревал, что когда это происходит, SDL_RWclose
освобождает уже освобожденный указатель, поэтому происходит сбой. Но когда SDL_RWclose
освобождает один из ресурсов, освобожденных TTF_CloseFont
, сам шрифт, этого не происходит. Еще одно указание мне на неопределенное поведение
Дополнительная информация: порядок, в котором освобождается ptr_mem_buff
(где хранится шрифт), не влияет на сбой (в моей среде).
Кроме того, установка указателей на nullptr
должна была решить проблему, так как free(nullptr)
ничего не дает. Но программа все равно вылетает даже после установки ptr_Font
на ноль после TTF_CloseFont(ptr_Font);
Как мне правильно освободить эти ресурсы?
Фрагмент кода:
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);
Этот звонок
ptr_Font = TTF_OpenFontRW(ptr_str_rwops2, 1, 72);
указывает TTF удалить поток RWOps (вот что означает 1). Вам не нужно закрывать этот поток, потому что вызов TTF_CloseFont()
сделает это. Вы ДЕЛАТЬ должны освободить ptr_mem_buff
, потому что поток RWOps этого не сделает.
Вы передаете
1
вTTF_OpenFontRW
, что означает, что он автоматически закроет и освободит источник. Я полагаю, вам следует либо пройти0
и вручную закрыть/освободитьptr_str_rwops2
, либо пройти1
и не закрывать/освобождать вручнуюptr_str_rwops2
.