В SDL SDL_Quit() освобождава ли всяка повърхност?

По принцип, на повърхности, които ще съществуват до края на програмата, трябва ли да стартирам SDL_FreeSurface() за всяка от тях или SDL_Quit() ще се погрижи за всичко това вместо мен?

Питам главно защото указателите към редица мои повърхности са членове на класа и следователно ще трябва да следя всеки екземпляр на клас (в глобален масив или нещо подобно), ако искам да стартирам SDL_FreeSurface() на всяка от съответните им повърхности. Ако SDL_Quit() ще направи всичко с един замах вместо мен, бих предпочел да го направя :D


person Lewis    schedule 23.06.2010    source източник


Отговори (3)


Измина известно време, откакто използвах SDL, но съм почти сигурен, че SDL_Quit просто почиства повърхността на екрана (основния екранен буфер, който сте настроили в началото). Трябва да освободите другите повърхности, които създавате ръчно, или ще получите течове. Разбира се, тъй като те вече са членове на класа, един от начините да направите това лесно е просто да ги освободите в деструктора на класа.

person Gemini14    schedule 23.06.2010
comment
Да, не е трудно да се освободи повърхността в деструктора, това просто би означавало да се следи всеки екземпляр на класа, тъй като повечето екземпляри на класа остават наоколо, докато програмата се затвори. Благодаря! - person Lewis; 23.06.2010
comment
Като се замисля, всичко излиза извън обхвата, след като main() е готово, така че всички деструктори така или иначе ще бъдат извикани при излизане. Така че няма нужда да следите всеки екземпляр! Поправете ме, ако греша, разбира се. - person Lewis; 24.06.2010
comment
Да, прав сте - освен ако самият съдържащ клас не е динамично разпределен (в който случай трябва да ги изтриете, разбира се), всичко ще бъде освободено автоматично, когато обектът излезе извън обхвата, както споменахте. - person Gemini14; 24.06.2010

Проверих изходния код на SDL 1.2.15, за да видя какво всъщност се случва, когато се извика SDL_Quit. Отговорът на Gemini14 е правилен: SDL_Quit ще освободи само основната SDL_Surface, върната от SDL_SetVideoMode.

Ето защо:

  1. SDLQuit извиква SDLQuitSubSystem за излизане от всяка подсистема
  2. SDLQuitSubSystem will call several subsystem quit functions
    • In particular, SDL_VideoQuit is called.
  3. SDL_VideoQuit first checks if the static global pointer current_video is not NULL.
    • If current_video is not NULL, the function precedes to clean up several global variables.
    • SDL_FreeSurface is called on SDL_ShadowSurface or SDL_VideoSurface
      • SDL_ShadowSurface or SDL_VideoSurface is initialized and returned from SDL_SetVideoMode

Тъй като SDL_FreeSurface се извиква само на основната SDL_Surface, инициализирана от SDL_SetVideoMode, можем да разсъждаваме, че всички други променливи на SDL_Surface, на които е разпределена памет, не са освободени с извикване на SDL_Quit и следователно трябва да бъдат освободени с изрични извиквания до SDL_FreeSurface.

Въпреки това, тъй като обикновено за всички програми операционната система ще освободи паметта автоматично, когато програмата приключи, освобождаването на променливите SDL_Surface е проблем само ако вашата програма продължи след SDL_Quit.

person Vilhelm Gray    schedule 03.07.2013

Най-добрата практика е да изчистите всичките си повърхности, които знаете, че използвате с SDL_FreeSurface().

По същия начин, ако създадете масив от указатели, които всички извикват malloc и следователно заемат пространство в купчина, излизането от програмата няма да изчисти цялото използвано пространство на всяка система.

int **memspots[1024];
for (i = 0; i < 1024; i++) {
  memspots[i] = malloc(1 * sizeof(int *)); // 1024 pointers to ints stored in heap memory
}

В края на кандидатстването ви определено бихте искали да се обадите безплатно по подобен начин.

for (i = 0; i < 1024; i++) {
  free(memspots[i]);
}

Най-добрата практика е да освобождавате всяка използвана памет по всяко време, когато е възможно, независимо дали по време на изпълнение и разбира се при изход.

Моята функция за GL текстура за SDL временно използва SDL_Surface, за да събере някои данни за изображение (взети от SDL_image) и има това в края:

  if (surface != NULL) // Will be NULL if everything failed and SOMEHOW managed to get here
    SDL_FreeSurface();

  return;
person Tatsh    schedule 23.06.2010