Как правильно освободить ресурсы, выделенные SDL_ttf? - PullRequest
2 голосов
/ 07 апреля 2019

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

2 голосов
/ 07 апреля 2019

Этот вызов

ptr_Font = TTF_OpenFontRW(ptr_str_rwops2, 1, 72);

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

...