SDL2 SIGSEGV从表面创建纹理

问题描述:

我想用SDL_CreateTextureFromSurface创建一个SDL_Texture。我已经多次成功地实现了这个功能,没有问题。目前我正在以下回溯信息:SDL2 SIGSEGV从表面创建纹理

#0 0xb7ef1e80 in ??() from /usr/lib/libSDL2-2.0.so.0 
#1 0xb7edf19c in ??() from /usr/lib/libSDL2-2.0.so.0 
#2 0xb7f12e1d in ??() from /usr/lib/libSDL2-2.0.so.0 
#3 0xb7f13ee7 in ??() from /usr/lib/libSDL2-2.0.so.0 
#4 0xb7eb2c08 in ??() from /usr/lib/libSDL2-2.0.so.0 
#5 0xb7e9f474 in SDL_CreateTextureFromSurface() from /usr/lib/libSDL2-2.0.so.0 
#6 0x0805999e in Building::draw (this=0xbfffe9a8, [email protected]: 0x81bd1b8) 
    at /code/directory/LIBRARY.h:194 
#7 0x08063df7 in main (argc=1, args=0xbffffac4) at Program.cpp:1151 

我的代码的其余部分和这个特殊的实现之间唯一不同的是,我的SDL_Surface是一个指针数组定义如下:

//<Initialize window and renderer (not included here)> 
SDL_Surface** Surf; 
SDL_Surface* SomeOtherSurface; 
int SurfSize = 0; 

SomeOtherSurface = LoadBMP("Filename.bmp"); 
for (i = 0; i < 2; i++) 
{ 
    Surf = (SDL_Surface**) realloc(Surf,SurfSize+1)*sizeof(SDL_Surface*)); 

    SDL_LockSurface(SomeOtherSurface); 
    Surf[i] = SDL_CreateRGBSurfaceFrom(SomeOtherSurface->pixels,SomeOtherSurface->w,SomeOtherSurface->h,32,SomeOtherSurface->pitch,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF); //Create a surface in Surf based on SomeOtherSurface 
    SDL_UnlockSurface(SomeOtherSurface); 
    SurfSize++; 
} 
SDL_FreeSurface(SomeOtherSurface); 
SDL_Texture* Tex1; 
Tex1 = SDL_CreateTextureFromSurface(Render,Surf[0]); //Create the texture; this throws the SIGSEGV 

我在程序的其他地方写了类似的代码,但并没有失败;任何人都可以找出这里发生了什么问题吗?该错误似乎表明内存有问题,但如果我尝试访问Surf [0] - > w,它会按预期返回值。

编辑:一些额外的信息可以帮助解决这个问题:在我的代码中,我定义纹理之前释放'SomeOtherSurface'表面。如果我在释放表面之前定义纹理,一切正常。这两个表面可能共享像素数据地址吗?

解决:我需要使用SDL_BlitSurface复制数据并修改它。如果我在使用SDL_CreateRGBSurfaceFrom之后继续释放表面,那么当程序尝试访问该存储器地址时,现有的像素数据也会被删除,导致段错误。

+0

在你的实际代码中,你是否将Surf初始化为第一个realloc()之前的空指针?你在这里呈现的realloc()调用不会编译(最后的附加括号),但是你可能要仔细检查你是否真的将realloc()返回的指针乘以一个指针的大小。 .. – notmyfriend

+0

是的,我错过了一个开放的支架。在realloc之前,Surf没有被初始化为null。 – Arlington

+0

那么..你应该在首次调用[realloc]之前将它初始化为null(http://en.cppreference.com/w/c/memory/realloc)。否则,如果内存位置碰巧包含0以外的内容,那么'realloc()'的行为是不确定的,因为传递的指针必须先被调用到'malloc()','calloc()'或'的realloc()'。 – notmyfriend

该代码的问题是SDL_CreateRGBSurfaceFrom使用现有的像素数据;因此,当您调用SDL_FreeSurface时,像素数据会丢失。现在,在调用SDL_CreateTextureFromSurface时,Surf [i]尝试查找像素数据,并且内存不可访问。

解决方案:使用SDL_BlitSurface复制像素数据以备后用。