早期调用了C++析构函数

C++ destructor called early

本文关键字:C++ 析构函数 调用      更新时间:2023-10-16

我有一个为我管理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纹理,这是正确的吗?如果我没有析构函数,只是浪费内存,代码就可以正常工作。我也尝试过将小狗作为局部变量并将其传递给渲染器,但这并没有帮助。

编辑:代码只运行一秒钟,然后崩溃。它不等待退出循环。此外,通过gdb的程序显示,由于某种原因,小狗至少被画了一次。我在这里上传了完整的来源:http://dl.getdropbox.com/u/2223161/sdlgame.zip

这是一个全局变量:

Entity puppy("puppy.bmp");

它在main()结束后被销毁,所以SDL_FreeSurfaceSDL_Quit()之后被调用。它有效吗?查看文档。

您看到的是问题的错误一端。在我将puppy的初始化移动到main之后,您的代码为我运行。

通过将puppy放置为全局对象,其构造函数在SDL_Init之前运行。构造函数调用load_image,后者调用SDL_DisplayFormat。文件警告:

在使用SDL_DisplayFormat函数之前,您必须调用SDL_Init。如果不这样做,您的程序将因访问违规而崩溃。

http://sdl.beuc.net/sdl.wiki/SDL_DisplayFormat

当然,您还应该确保析构函数在SDL_Quit()之前被调用,这是正确的,尽管这不是目前导致访问冲突的原因。