在 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_FreeSurface
在 SDL_ShadowSurface
或 SDL_VideoSurface
上调用
SDL_ShadowSurface
或 SDL_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() 是不是释放每个表面?的主要内容,如果未能解决你的问题,请参考以下文章