【发布时间】:2016-10-15 22:38:12
【问题描述】:
所以我一直在阅读lazyfoos SDL2 教程,我只是好奇为什么所有SDL_Surface/SDL_textures 等都是在堆上创建的?我意识到 SDL 本身是用 C 语言编写的,并且函数接受/返回指针,但为什么不在堆栈上创建表面并将其引用传递给函数呢? (或在分配时取消引用它)
希望我已经清楚了。这里有一段代码sn-p来进一步解释一下:
为什么会这样:
void pointer()
{
SDL_Surface *windowsurface;
SDL_Surface *surface = SDL_LoadBMP("asdf.bmp");
SDL_BlitSurface(surface, 0, windowsurface, 0);
}
而不是这个:
void stack()
{
SDL_Surface windowsurface;
SDL_Surface surface = *(SDL_LoadBMP("asdf.bmp"));
SDL_Blit(&surface, 0, &windowsurface, 0);
}
如果后者确实可行,您还需要致电SDL_FreeSurface 吗?如果是这样,这将确保您不会泄漏任何内存,所以我不太了解前者的好处。
希望这一切都有意义,在 SDL 方面我仍然是新手
【问题讨论】:
-
这很可能是因为 SDL 的对象具有 SDL 库必须跟踪的内部资源。这要求 SDL 对象的所有实例化和销毁都由库直接完成,只有库负责 100% 的对象生命周期管理;因此唯一可能的实现是基于堆的分配和销毁。
-
所以我必须在堆上创建所有表面?我问的原因是因为我有很多以纹理为成员的类,并且希望避免担心我所有类的复制构造函数和分配。
-
在第二个示例中,
windowsurface在函数退出时被销毁。我想大多数纹理需要比创建它们的函数寿命更长。 -
通常的解决方案是为原生 C 对象提供一个包装器,就像 SDL 库中的那些,使用 std::shared_ptr 来引用对象,并让包装器负责销毁本机使用库的适当析构函数的 C 对象。
-
堆栈大小,一般来说不适合图片。默认linux栈大小为8M(ulimit -s查看)。
标签: c++ pointers memory sdl heap-memory