Как правильно освободить ресурсы, выделенные SDL_ttf?

Я последовал советам в предыдущий вопрос и решил проблему с загрузкой файла в память. Однако я обнаружил проблему, когда освобождал ресурсы. Если я попытаюсь освободить файл 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);

Вы передаете 1 в TTF_OpenFontRW, что означает, что он автоматически закроет и освободит источник. Я полагаю, вам следует либо пройти 0 и вручную закрыть/освободить ptr_str_rwops2, либо пройти 1 и не закрывать/освобождать вручную ptr_str_rwops2.

Cornstalks 07.04.2019 02:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
169
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Этот звонок

ptr_Font = TTF_OpenFontRW(ptr_str_rwops2, 1, 72);

указывает TTF удалить поток RWOps (вот что означает 1). Вам не нужно закрывать этот поток, потому что вызов TTF_CloseFont() сделает это. Вы ДЕЛАТЬ должны освободить ptr_mem_buff, потому что поток RWOps этого не сделает.

Другие вопросы по теме