我有一个为我管理SDL_Surface的类,我想这样做,以便我不必担心释放表面。到目前为止我有这个代码:
//In Entity.h
class Entity
{
public:
int x, y, width, height;
Entity(std::string);
~Entity();
void render();
private:
SDL_Surface* texture;
};
//In Entity.cpp
Entity::~Entity()
{
printf("Destroying an Entity");
SDL_FreeSurface(texture);
}
//In main.cpp
Entity puppy("puppy.bmp");
void render() {
clearScreen();
puppy.render();
}
int main (int argc, char **argv) {
printf("started");
init();
bool done = false;
while(!done)
{
...
// Draw the screen
printf("About to render");
render();
SDL_Flip(screen);
}
SDL_Quit();
return 0;
}
当我运行它时,我得到Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000260
0x000000010002fd9b in SDL_DisplayFormat ()
我是否正确假设析构函数被提前调用并且它正在尝试渲染NULL纹理?如果我没有析构函数并且只是浪费内存,代码工作正常。我也尝试过将puppy作为局部变量并将其传递给渲染,但这没有用。
编辑:代码只运行一秒钟,然后崩溃。它不等待退出循环。此外,使用gdb逐步执行程序会显示出由于某种原因至少要抽出一次小狗。我在这里上传了完整的来源:http://dl.getdropbox.com/u/2223161/sdlgame.zip
答案 0 :(得分:3)
这是一个全局变量:
Entity puppy("puppy.bmp");
它会在main()
结束后被销毁,因此SDL_FreeSurface
会在SDL_Quit()
之后被调用。有效吗?查看文档。
答案 1 :(得分:2)
你正在看问题的错误结局。我将puppy
的初始化移动到main
。
将puppy
作为全局对象放置,其构造函数在SDL_Init
之前运行。构造函数调用load_image
,调用SDL_DisplayFormat
。文件警告说:
在使用
SDL_Init
功能之前,您必须先致电SDL_DisplayFormat
。如果不这样做,您的程序将因访问冲突而崩溃。
http://sdl.beuc.net/sdl.wiki/SDL_DisplayFormat
当然,你也应该确保在SDL_Quit()
之前调用析构函数,这是正确的,尽管这不是导致你的访问违规的原因。