我试图基于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时会出现问题,我认为这应该是有效的,但由于某种原因,它不是。我究竟做错了什么?发布更多代码会有帮助吗?
答案 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
这是非常重要的创建自己。