我正在测试我将在我的游戏项目中使用的TextureManager类,但我遇到的问题是当我尝试将2d纹理加载到std :: map时.exe会崩溃。我需要的是我有一个指向SDL_Textures的指针映射,用标准字符串键入
std::map<std::string, SDL_Texture*>Textures;
SDL和SDL_image初始化ok(控制台中的成功printfs)但是一旦调用了load()函数,纹理映射就会启动并且程序崩溃。下面是函数的实现
void TextureManager::load( std::string path, std::string id )
{
SDL_Surface* TempSurface = IMG_Load( path.c_str() );
if( TempSurface == NULL )
{
printf( "Failed to load %s: error: %s\n", path.c_str(), IMG_GetError() );
}
/* add color coding if necessary here
SDL_SetColorKey( TempSurface, SDL_TRUE, SDL_MapRGB( TempSurface->format, 0, 0xFF, 0xFF ) );
*/
SDL_Texture* newTexture = SDL_CreateTextureFromSurface( renderer, TempSurface );
if( newTexture == NULL )
{
printf( "Failed to create a texture %s: error: %s\n", id.c_str(), SDL_GetError() );
}
SDL_FreeSurface( TempSurface );
Textures[ id ] = newTexture;
printf( "Texture %s mapped successfully", id.c_str() );
//possible error - not the cause of the described error
//SDL_DestroyTexture( newTexture );
}
当然,Textures map是TextureManager类的私有成员。如果函数是由TextureManager的构造函数调用,或者稍后由指向TextureManager的指针调用,则无关紧要 - 结果相同。这个加载器的先前版本没有映射纹理,地图根本没有使用,它工作得很好。那么地图应该受到指责吗?这是版本之间的唯一区别......
编辑我已在最后一个代码行中添加了其他评论并对其进行了“评论”,因为在我测试了建议之后它是错误的原因,程序的行为没有改变所以它必须是其他的。
EDIT2:好的,我已经解决了这个问题 - 碰巧其中一个表面是从.jpg文件加载的,并且由于某种原因,jpg sdl库文件已损坏。因此,JPG支持在运行时没有初始化,并且尝试加载jpg文件会导致exe崩溃。替换项目文件夹中的.dll已解决了问题 - 一切正常按预期工作
答案 0 :(得分:0)
Textures[id] = newTexture;
SDL_DestroyTexture(newTexture);
这会留下指向已在map<std::string, SDL_Texture*>
(或您正在使用的类似数据结构)中释放的纹理的指针。只有当你不再需要时才应该破坏纹理,而不仅仅是在加载之后。
这是一个悬空指针,因为SDL_CreateTextureFromSurface
返回一个有效SDL_Texture
实例的地址,该实例在销毁之后变为无效,因此Textures[id]
指向一个不再分配的地址。