Reputation: 253
I'm learning how to use SDL library to graphic programming and I am having a segmentation fault on the next code:
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 variable comes from this function:
SDL_Surface * draw = SDL_CreateRGBSurface(SDL_SWSURFACE, ANCHO, ALTO, 24,rmask, gmask,bmask, amask);
The struct sit_per is the following:
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;
};
And the img array was filled with the next function:
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;
}
I'm sure that the route to the images are well writed, and I can say that the x and y coordinates are well too.
I'll apreciate any suggestion, thanks in advance.
Upvotes: 0
Views: 307
Reputation: 9661
There are several oddness in your code.
First,
int situador(SDL_Surface * dib,struct sit_per per)
{
SDL_Rect pos;
struct sit_per * est;
est=&per;
let it be
int situador(SDL_Surface * dib,struct sit_per *per)
{
SDL_Rect pos;
struct sit_per * est = per; // assignment can be made later
just style and avoiding too much data and copying on the stack.
The use of the for loop could be also an option;
for(est = per; est != NULL; est = est->si)
If a function returns always a fixed value, you can make it return nothing...; so, void situador(...)
instead of int situador(...)
.
The function creador
load 9 images, when only 8 are needed (one per direction, I suppose), this is the source for the segfault; do not hard encode (absolute) paths to files, as said before.
To exit a for loop, use the break keyword, avoid in general the modification of the loop variable (unless you have a good reason, and here I can't see one). Again, the for loop loops for 9 images, where you have room just for 8 in your array. If you need the 9th image, you have to write SDL_Surface * img[9];
. It could be confusing, but when you declare an array, the number between brackets is the number of items, while when accessing, the index is 0-based so that the last element has index N-1.
So the whole final piece can become
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;
usually it is better to use named constants, instead of number; e.g.
#define NUM_OF_ELEMENT 8
#define NUM_OF_DES 50
and so
struct personaje
{
char des[NUM_OF_DES];
SDL_Surface * img[NUM_OF_ELEMENT];
int dir;
int x;
int y;
};
and so on... (of course you will pick another name, like NUM_OF_DIRS or NUM_OF_IMAGES or whatever is your meaningful prefered form in your language)
Upvotes: 1
Reputation: 753475
Your code loads 9 image pointers into an array of 8 elements.
This is not a recipe for happiness.
Upvotes: 4