我正在学习如何使用SDL库进行图形编程,我在下一段代码中遇到了分段错误:
int situador(SDL_Surface * dib,struct sit_per per)
{
SDL_Rect pos;
struct sit_per * est;
est=&per;
while(est)
{
pos.x = est->ac->x;
pos.y = est->ac->y;
pos.w = est->ac->img[est->ac->dir]->w;
pos.h = est->ac->img[est->ac->dir]->h;
SDL_BlitSurface(est->ac->img[est->ac->dir], NULL, dib, &pos);
est=est->si;
}
return 0;
}
dib变量来自此函数:
SDL_Surface * draw = SDL_CreateRGBSurface(SDL_SWSURFACE, ANCHO, ALTO, 24,rmask, gmask,bmask, amask);
struct sit_per如下:
struct sit_per
{
struct personaje * ac;
struct sit_per * si;
};
struct personaje
{
char des[50];
SDL_Surface * img[8];
int dir;
int x;
int y;
};
img数组填充了下一个函数:
struct personaje * creador(char * cad)
{
int x;
struct personaje * per;
per=(struct personaje *)malloc(sizeof(struct personaje));
strcpy(per->des,cad);
per->img[0] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/0.bmp");
per->img[1] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/1.bmp");
per->img[2] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/2.bmp");
per->img[3] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/3.bmp");
per->img[4] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/4.bmp");
per->img[5] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/5.bmp");
per->img[6] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/6.bmp");
per->img[7] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/7.bmp");
per->img[8] = SDL_LoadBMP("/home/andoni/SDL/img/flecha/8.bmp");
for(x=0;x<9;x++)
if(!per->img[x])
x=10;
if(x==10)
return NULL;
else
return per;
}
我确信通往图像的路线写得很好,我可以说x和y坐标也很合适。
我会提前感谢任何建议。
答案 0 :(得分:4)
您的代码将9个图像指针加载到8个元素的数组中。
这不是快乐的秘诀。
答案 1 :(得分:1)
您的代码有几个奇怪的地方。
首先,
int situador(SDL_Surface * dib,struct sit_per per)
{
SDL_Rect pos;
struct sit_per * est;
est=&per;
让它成为
int situador(SDL_Surface * dib,struct sit_per *per)
{
SDL_Rect pos;
struct sit_per * est = per; // assignment can be made later
只是样式并避免过多的数据并在堆栈上复制。
使用for循环也可以选择;
for(est = per; est != NULL; est = est->si)
如果一个函数总是返回一个固定值,你就可以使它不返回...;所以,void situador(...)
代替int situador(...)
。
函数creador
加载9个图像,当只需要8个图像时(我想每个方向一个),这是段错误的来源;如前所述,不要硬编码(绝对)文件路径。
要退出for循环,请使用 break 关键字,一般避免修改循环变量(除非你有充分的理由,在这里我看不到一个)。同样,for循环循环9个图像,你的数组中只有8个空间。如果您需要第9张图片,则必须编写SDL_Surface * img[9];
。这可能会令人困惑,但是当您声明一个数组时,括号之间的数字是项目数,而在访问时,索引是从0开始的,因此最后一个元素的索引为N-1。
所以整个最终作品可以成为
for(x = 0; x < NUM_OF_ELEMENT; x++)
if(!per->img[x])
break;
if (x < NUM_OF_ELEMENT)
{
int y;
for(y = 0; y < x; y++)
SDL_func_to_free_loaded_images(per->img[y]);
free(per);
return NULL;
}
else
return per;
通常最好使用命名常量而不是数字; e.g。
#define NUM_OF_ELEMENT 8
#define NUM_OF_DES 50
等等
struct personaje
{
char des[NUM_OF_DES];
SDL_Surface * img[NUM_OF_ELEMENT];
int dir;
int x;
int y;
};
等等......(当然,您会选择其他名称,例如NUM_OF_DIRS或NUM_OF_IMAGES或您的语言中任何有意义的首选表单)