早期调用C ++析构函数

时间:2012-02-18 00:30:41

标签: c++ memory-management sdl

我有一个为我管理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

2 个答案:

答案 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()之前调用析构函数,这是正确的,尽管这不是导致你的访问违规的原因。