当我试图检查NULL时,EXC_BAD_ACCESS

时间:2016-12-22 07:29:09

标签: c++ xcode memory null sdl-2

我试图基于LazyFoo的精彩教程(http://lazyfoo.net/tutorials/SDL/10_color_keying/index.php)来实现一个简单的Color Keying引擎示例,但是当我尝试运行它时,该线程给了我一个EXC_BAD_ACCESS(代码=尽管我试图测试该指针是否为空,但是指针上的1,地址= 0x0)。这是班级的样子:

//Texture wrapper class
class LTexture
{
public:
    //Initializes variables
    LTexture();
    //Deallocates memory
    ~LTexture();
    //Loads image at specified path
    bool loadFromFile(std::string path);
    //Deallocates texture
    void free();
    //Renders a texture at a given point
    void render(int x, int y);
    //Gets an image's dimensions
    int getWidth();
    int getHeight();
private:
    //The actual hardware texture
    SDL_Texture* mTexture = NULL;
    //Image dimensions
    int mWidth;
    int mHeight;
};

这里有初始化和破坏方法:

LTexture::LTexture()
{
    //Initialize
    mTexture = NULL;
    mWidth = 0;
    mHeight = 0;
    printf("I initialized");
}

LTexture::~LTexture()
{
    free();
}

我的错误在于LTexture::free方法。

void LTexture::free()
{
    //Free texture if it exists
    if (mTexture != NULL) //HERE IS THE ISSUE. WHAT IS WRONG WITH THIS?
    {
        SDL_DestroyTexture(mTexture);
        mTexture = NULL;
        mWidth = 0;
        mHeight = 0;
    }
}

正如你可以看到的那样,当我测试mTexture是否为NULL时会出现问题,我认为这应该是有效的,但由于某种原因,它不是。我究竟做错了什么?发布更多代码会有帮助吗?

1 个答案:

答案 0 :(得分:0)

问题可能是您没有正确处理复制和移动。

每当您复制LTexture时,只会复制指针。如果副本超出范围,则调用析构函数。然后,原始版本在某个时刻超出范围,并且在同一指针上再次调用析构函数,导致双重释放。

我建议使用智能指针:

#include <memory>
class TextureDeleter { void operator()(SDL_Texture* t) { SDL_DestroyTexture(t); };

// in the class
std::unique_ptr<SDL_Texture, TextureDeleter> mTexture;

然后您可以删除析构函数。

编辑:如果您真的不想使用<memory>,那么只需添加

LTexture(const LTexture &) = delete;
LTexture& operator=(const LTexture &) = delete;
LTexture(LTexture &&) = delete;
LTexture& operator=(LTexture &&) = delete;

到你的班级。

但是,正如评论中指出的那样,只有在您实际上不需要移动或复制课程时,这才有效。如果你这样做,你必须使用shared_ptr这是非常重要的创建自己。