В SDL освобождает ли SDL_Quit () все поверхности? - PullRequest
3 голосов
/ 23 июня 2010

В основном, на поверхностях, которые будут существовать прямо до завершения программы, нужно ли мне запускать SDL_FreeSurface() для каждой из них, или SDL_Quit() позаботится обо всем этом для меня?

Я спрашиваю в основном потому, что указатели на ряд моих поверхностей являются членами класса, и поэтому мне нужно будет отслеживать каждый экземпляр класса (в глобальном массиве или что-то в этом роде), если я хочу запустить SDL_FreeSurface() на каждом из их соответствующие поверхности. Если SDL_Quit () сделает все это одним махом для меня, я бы предпочел пойти на это: D

Ответы [ 3 ]

3 голосов
/ 03 июля 2013

Я проверил исходный код SDL 1.2.15 , чтобы увидеть, что на самом деле происходит при вызове SDL_Quit. Ответ Gemini14 правильный: SDL_Quit освободит только основную SDL_Surface, возвращаемую SDL_SetVideoMode.

Вот почему:

  1. SDLQuit звонки SDLQuitSubSystem для выхода из каждой подсистемы
  2. SDLQuitSubSystem вызовет несколько функций выхода из подсистемы
    • В частности, вызывается SDL_VideoQuit.
  3. SDL_VideoQuitСначала проверяется, не является ли статический глобальный указатель current_video ненулевым.
    • Если current_video не равен NULL, функция предшествует очистке нескольких глобальных переменных.
    • SDL_FreeSurface вызывается для SDL_ShadowSurface или SDL_VideoSurface
      • SDL_ShadowSurface или SDL_VideoSurface инициализируется и возвращается из SDL_SetVideoMode

Поскольку SDL_FreeSurface является только , вызываемым наmain SDL_Surface, инициализированный SDL_SetVideoMode, мы можем утверждать, что все другие переменные, выделенные памяти SDL_Surface, не освобождены при вызове SDL_Quit и поэтому должны быть освобождены при явных вызовах SDL_FreeSurface.

Однако, поскольку, как правило, для всех программ операционная система автоматически освобождает память после ее завершения, освобождение переменных SDL_Surface является проблемой, только если ваша программа продолжит работу после SDL_Quit.

2 голосов
/ 23 июня 2010

Прошло много времени с тех пор, как я использовал SDL, но я почти уверен, что SDL_Quit просто очищает поверхность экрана (буфер основного экрана, который вы установили в начале). Вы должны освободить другие поверхности, которые вы создали вручную, или вы получите утечки. Конечно, поскольку они уже являются членами класса, одним из способов сделать это было бы просто освободить их в деструкторе класса.

1 голос
/ 23 июня 2010

Лучше всего очистить все поверхности, которые, как вы знаете, используете, с помощью 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;
...