在SDL中,SDL_Quit()是否可以释放每个表面?

时间:2010-06-23 05:55:33

标签: c++ c sdl surface

基本上,在程序终止之前存在的表面上,我是否需要为每个表面运行SDL_FreeSurface(),或者SDL_Quit()为我处理所有这些问题?

我问主要是因为指向我的许多表面的指针是类成员,因此如果我想运行SDL_FreeSurface(),我需要跟踪每个类实例(在全局数组或其他内容中)他们各自的表面。如果SDL_Quit()会一举为我做这件事,我宁愿选择:D

3 个答案:

答案 0 :(得分:3)

我查看了 SDL 1.2.15 源代码,了解调用SDL_Quit时实际发生的情况。 Gemini14's answer是正确的:SDL_Quit只会释放SDL_SetVideoMode返回的主SDL_Surface。

原因如下:

  1. SDLQuit调用SDLQuitSubSystem退出每个子系统
  2. SDLQuitSubSystem将调用多个子系统退出函数
    • 特别要调用SDL_VideoQuit
  3. SDL_VideoQuit首先检查静态全局指针current_video是否不为NULL。
    • 如果current_video不为NULL,则该函数先于清除多个全局变量。
    • SDL_FreeSurfaceSDL_ShadowSurface上调用
    • SDL_VideoSurface
      • SDL_ShadowSurfaceSDL_VideoSurface已初始化并从SDL_SetVideoMode
      • 返回
  4. 由于SDL_FreeSurface仅在SDL_SetVideoMode初始化的主SDL_Surface上调用了 ,我们可以推断所有其他SDL_Surface变量分配的内存通过调用SDL_Quit释放,因此必须通过显式调用SDL_FreeSurface来释放。

    但是,由于通常对于所有程序,操作系统将在程序结束时自动释放内存,如果程序在SDL_Quit之后继续,则释放SDL_Surface变量只是一个问题。

答案 1 :(得分:2)

我使用SDL已经有一段时间了,但我很确定SDL_Quit只是清理屏幕表面(你在开始时设置的主屏幕缓冲区)。您必须释放手动创建的其他曲面,否则会泄漏。当然,既然他们已经是班级成员,那么轻松做到这一点的一种方法就是在类析构函数中释放它们。

答案 2 :(得分:1)

最佳做法是使用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]);
}

最佳做法是尽可能随时释放所有使用的内存,无论是在运行时还是在退出时。

SDL的我的GL纹理功能暂时使用SDL_Surface来收集一些图像数据(取自SDL_image)并在最后得到它:

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

  return;