在 SDL 中,SDL_Quit() 是不是释放每个表面?

Posted

技术标签:

【中文标题】在 SDL 中,SDL_Quit() 是不是释放每个表面?【英文标题】:In SDL, does SDL_Quit() free every surface?在 SDL 中,SDL_Quit() 是否释放每个表面? 【发布时间】:2011-03-07 04:01:16 【问题描述】:

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

我问主要是因为指向我的许多表面的指针是类成员,因此如果我想在每个表面上运行 SDL_FreeSurface(),我需要跟踪每个类实例(在全局数组或其他东西中)它们各自的表面。如果 SDL_Quit() 会一举为我完成这一切,我宁愿继续这样做:D

【问题讨论】:

【参考方案1】:

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

原因如下:

    SDLQuit 调用 SDLQuitSubSystem 退出每个子系统 SDLQuitSubSystem 将调用几个子系统退出函数 特别是,SDL_VideoQuit 被调用。 SDL_VideoQuit 首先检查静态全局指针 current_video 是否不为 NULL。 如果current_video 不为NULL,该函数会先清理几个全局变量。 SDL_FreeSurfaceSDL_ShadowSurfaceSDL_VideoSurface 上调用 SDL_ShadowSurfaceSDL_VideoSurface 被初始化并从 SDL_SetVideoMode 返回

由于SDL_FreeSurface在由SDL_SetVideoMode 初始化的主 SDL_Surface 上调用,我们可以推断分配内存的所有其他 SDL_Surface 变量不会通过调用释放到SDL_Quit,因此必须通过显式调用SDL_FreeSurface 来释放。

但是,由于通常对于所有程序,操作系统都会在程序结束时自动释放内存,因此只有在您的程序在SDL_Quit 之后继续运行时才需要考虑释放 SDL_Surface 变量。

【讨论】:

【参考方案2】:

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

【讨论】:

是的,在析构函数中释放表面并不难,它只是意味着跟踪类的每个实例,因为大多数类实例会一直保留到程序退出。谢谢! 想想看,main() 完成后一切都超出了范围,因此无论如何都会在退出时调用所有析构函数。因此无需跟踪每个实例!当然,如果我错了,请纠正我。 是的,你是对的——除非包含类本身是动态分配的(在这种情况下你必须删除它们,当然),当对象退出时,一切都会自动释放范围,正如你提到的。【参考方案3】:

最好使用 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

在您的应用程序结束时,您肯定希望以类似的方式调用 free。

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;

【讨论】:

以上是关于在 SDL 中,SDL_Quit() 是不是释放每个表面?的主要内容,如果未能解决你的问题,请参考以下文章

流媒体开发15SDL-YUV播放

流媒体开发15SDL-YUV播放

C ++ SDL2:如何将矩形渲染到多个视口中

使用 OpenGL 正确关闭 SDL

如何正确检测 sdl2 中的按键按下和释放

在 SDL 2 中获取连续的窗口调整大小事件