Seg Fault while trying to display image

I am writing a game with SDL and C. I have one animated image being displayed on the screen. I want to display a background underneath it. This is, however, not working at all. Here is my code. The backdrop part is where it seg faults. I must be missing something simple.

Code:

struct character
{
struct stats status;
struct physics physics;
struct image image;
struct animation *left,*right,*up,*down,*active;
};

struct image
{
const char *fname;
SDL_Surface *surface;
};

struct animation
{
struct image image;

struct animation *next;
};

struct character Main;
struct image backdrop;

void gameInit()
{
loadImage("./images/c1_1.bmp", &Main.down->image);
Main.active=Main.down;

Main.physics.x=100;
Main.physics.y=200;

loadImage("./images/testbg.bmp",&backdrop);

return;
}

void gameRender()
{
show(0,0,&backdrop); //Seg Fault here

show(Main.physics.x, Main.physics.y, &Main.active->image);
Main.active=Main.active->next;

display();

return;
}

void show(double x, double y, struct image *obj)
{
SDL_Rect src, dest;

src.x = 0;
src.y = 0;
src.w = obj->surface->w;
src.h = obj->surface->h;

dest.x = x;
dest.y = y;
dest.w = obj->surface->w;
dest.h = obj->surface->h;

SDL_BlitSurface(obj->surface, &src, screen, &dest);

return;
}

void loadImage(const char *fname, struct image *obj)
{
obj->fname=fname;
SDL_Surface *temp = SDL_LoadBMP(fname);
obj->surface = SDL_DisplayFormat(temp);
SDL_FreeSurface(temp);

//SDL_SetAlpha(obj->surface, SDL_SRCALPHA | SDL_RLEACCEL, 0xFF);
SDL_SetColorKey(obj->surface, SDL_SRCCOLORKEY, SDL_MapRGB(obj->surface->format, 0x0, 0xFF, 0x0));

return;
}

So this is your real code? No error checking at all? Are images even loaded? SDL initialized? Did you even bothered to debug this code on your own? 95% chance that Segfault is cause by invalid pointer use.

I am not insulting anybody. Just commenting what I was given. You didn’t wrote it is partial code and what you already tried. That said, give us real code that fails, not the part you think is relevant. Also, I see what loadImage TRIES to do not what it does, since it returns no value to a caller (gameInit function) has no idea if image was correctly loaded. Do not get upset just because I asked questions.

hardcoder wrote:

So this is your real code? No error checking at all? Are images even loaded? SDL initialized? Did you even bothered to debug this code on your own? 95% chance that Segfault is cause by invalid pointer use.

Its not all the code obviously, and I left a few lines out so as to not be confusing. Just the parts that are necessary to see the problem.
Like I said, the first image IS displayed if I comment out the show(0,0,&backdrop) line.
Yes, the images are loaded, thats what loadImage() does.
I spent days debugging this already. If its a pointer problem, show me where it is, because I’ve been looking and looking, I can’t find it.
I asked for help, not an insult.

hardcoder wrote:

I am not insulting anybody. Just commenting what I was given. You didn’t wrote it is partial code and what you already tried. That said, give us real code that fails, not the part you think is relevant. Also, I see what loadImage TRIES to do not what it does, since it returns no value to a caller (gameInit function) has no idea if image was correctly loaded. Do not get upset just because I asked questions.

Alright. I’ll try to be more thorough in my explanation. I do have to get up for work in the morning though, its almost 11:30 at night here in Taiwan.
I have made some changes to my code since my previous post. I’ll try to explain everything I’ve done and why. I can’t post ALL my code because, even at this early stage, theres quite a lot of code. Heres what I have now:

Code:

#include <SDL/SDL.h>

struct image
{
const char *fname;
SDL_Surface *surface;
};

struct animation
{
struct image image;

struct animation *next;

};

struct stats
{
char name[32];
unsigned int attack,
defense,
health,
max_ammo;
};

struct physics
{
double x, y,
dir;
};

struct character
{
struct stats status;
struct physics physics;
struct image image;
struct animation *left,*right,*up,*down,*active;
};

struct character Main, BG;

void windowInit(const char * title, short unsigned int width, short unsigned int height)
{
SDL_Init(SDL_INIT_VIDEO);

SDL_WM_SetCaption(title, title);

screen = SDL_SetVideoMode(width, height, 16, SDL_DOUBLEBUF);

// screen = SDL_SetVideoMode(width, height, 16, SDL_DOUBLEBUF | SDL_FULLSCREEN);

return;

}

void display()
{
SDL_Flip(screen);

return;

}

void show(double x, double y, struct image obj)
{
SDL_Rect src, dest;

printf("%d:%d\n",obj,obj.surface);

src.x = 0;
src.y = 0;
printf("1\n");
src.w = obj.surface->w;
src.h = obj.surface->h;
printf("2\n");

printf("3\n");
dest.x = x;
dest.y = y;
printf("4\n");
dest.w = obj.surface->w;
dest.h = obj.surface->h;

SDL_BlitSurface(obj.surface, &src, screen, &dest);

return;

}

struct animation *animation_create_frames(unsigned short int frames)
{
int i;
struct animation *tmp, *start;

start=malloc(sizeof(struct animation));
tmp=start;
for (i=1;i<frames;i++)
{
	tmp->next=malloc(sizeof(struct animation));
	tmp=tmp->next;
}
tmp->next=start;

return start;

}

void delay(Uint32 i)
{
SDL_Delay(i);

return;

}

void loadImage(const char *fname, struct image *obj)
{
obj->fname=fname;
SDL_Surface *temp = SDL_LoadBMP(fname);
obj->surface = SDL_DisplayFormat(temp);
SDL_FreeSurface(temp);

//SDL_SetAlpha(obj->surface, SDL_SRCALPHA | SDL_RLEACCEL, 0xFF);
SDL_SetColorKey(obj->surface, SDL_SRCCOLORKEY, SDL_MapRGB(obj->surface->format, 0x0, 0xFF, 0x0));

printf("%d::%d\n",obj,obj->surface);
return;

}

void gameInit()
{
BG.active=malloc(sizeof(struct animation));
loadImage("./images/testbg.bmp",&BG.active->image);

Main.down=animation_create_frames(4);
loadImage("./images/c1_1.bmp", &Main.down->image);
loadImage("./images/c1_2.bmp", &Main.down->next->image);
loadImage("./images/c1_1.bmp", &Main.down->next->next->image);
loadImage("./images/c1_3.bmp", &Main.down->next->next->next->image);
Main.active=Main.down;

Main.physics.x=100;
Main.physics.y=200;

return;

}

void gameRender()
{
printf("%d:%d\n",Main.active->image,Main.active->image.surface);
show(Main.physics.x, Main.physics.y, Main.active->image);
Main.active=Main.active->next;

printf("%d:%d\n",BG.active->image,BG.active->image.surface);
show(0,0,BG.active->image);

display();

return;

}

int quit=false;

int main ( int argc, char *argv[] )
{
windowInit(“The Lesser Evil”,640,480);

gameInit();

#ifdef DEBUG
SDL_version ver;

// Prints the compile time version
SDL_VERSION(&ver);
printf("SDL Version: %u.%u.%u\n", ver.major, ver.minor, ver.patch);

// Prints the run-time version
ver = *SDL_Linked_Version();
printf("SDL Runtime Version: %u.%u.%u\n", ver.major, ver.minor, ver.patch);
#endif

while (!quit)
{
	gameRender();
	delay(1000/5);
}


return 0x14;

}

Ok, there it is. I added a bunch of printf to determine where and why this is happening. I changed “struct image backdrop” to “struct character BG” so I could do the exact same thing with Main and BG. Main works, BG still does not. I also use a circularly-linked list for an animation. Here is some sample output from the program:

Code:
13733488::13808336
13733760::13734000
13733792::13734240
13733824::13739360
13733856::13739600
SDL Version: 1.2.13
SDL Runtime Version: 1.2.13
4199076:13734000
4199076:13734000
1
2
3
4
4199056:13808336
0:0
1
Segmentation fault

The first few lines confirm that the images are getting loaded correctly. Then my SDL version numbers. Then the memory addresses of Main.active and Main.active->image before and after it gets passed to show(). Then 1 2 3 4 showing that show() didn’t crash that time.
As you can see from the last 3 lines before the segfault, the problem is occurring in the show function. I try to pass BG to it, but the function sees it as 0. weird because when I do the exact same thing with Main it works fine. If I just comment out the line where I show(BG), then it runs fine and I see my little walking guy on a black screen.

Here is some GDB output

Code:
This GDB was configured as “x86_64-linux-gnu”…
(gdb) run
Starting program: /home/prushik/Sandbox/games/Lesser Evil/debug
[Thread debugging using libthread_db enabled]
[New Thread 0x7f884eace6f0 (LWP 29836)]
17c1e70::17d42d0
17c1f80::17c2070
17c1fa0::17c2160
17c1fc0::17c3560
17c1fe0::17c3650
SDL Version: 1.2.13
SDL Runtime Version: 1.2.13
401214:17c2070
401214:17c2070
401200:17d42d0
0:0

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f884eace6f0 (LWP 29836)]
0x0000000000400cf6 in show (x=200, y=200, obj={fname = 0x0, surface = 0x0})
at graphics_sdl.c:65
65 src.w = obj.surface->w;
(gdb) p obj
$1 = {fname = 0x0, surface = 0x0}
(gdb) p obj.surface
$2 = (SDL_Surface *) 0x0
(gdb) p BG
$3 = {status = {name = ‘\0’ <repeats 31 times>, attack = 0, defense = 0,
health = 0, max_ammo = 0}, physics = {x = 0, y = 0, dir = 0}, image = {
fname = 0x0, surface = 0x0}, left = 0x0, right = 0x0, up = 0x0,
down = 0x0, active = 0x17c1e70}
(gdb) p BG.active
$4 = (struct animation *) 0x17c1e70
(gdb) p BG.active->image
$5 = {fname = 0x401200 “./images/testbg.bmp”, surface = 0x17d42d0}
(gdb) q
The program is running. Exit anyway? (y or n) y

retardedtroglodyte wrote:

Main.down->image=malloc(sizeof(struct image));
I noticed that seems to be the one thing you do to the character image that you don’t do for the backdrop
if the character loads up and the backdrop doesn’t maybe you have to do that for the backdrop too?

void gameInit()
{
Main.down->image=malloc(sizeof(struct image));
loadImage("./images/c1_1.bmp", &Main.down->image);
Main.active=Main.down;

Main.physics.x=100;
Main.physics.y=200;
//maybe it fails because you didn’t allocate the size of the image struct in the backdrop?
//backdrop=malloc(sizeof(struct image)); <- maybe something like this?
loadImage("./images/testbg.bmp",&backdrop);

return;
}

worth a shot I guess :confused:

That was a bit of a mistake. I accidentally removed that line when I copied the code over, I added it in again after I pasted it, it should have been Main.down=malloc(sizeof(struct animation));
backdrop isn’t declared as a pointer so I don’t need to allocate memory for it explicitly. I did change this however, take a look a few posts later, I posted my updated code, and a better explanation of what I’m doing.

Sorry for late reply, I was away for last few days. I just complied your code and tried it just to find out it works OK.

I had to remove debug printfs thou, because of compiler complaining about “%d” used to print a struct.

Could you check for errors in more traditional way? Like:

SDL_Surface* temp = SDL_LoadBMP(path);

if (temp == 0)
{
printf(“Error loading image %s %s”, path, SDL_GetError());
{

I used gcc 4.4.1 32 bit version. Indeed it is impossible that such a fundamental thing like built-in type conversion is implemented incorrectly in gcc compiler. I would rather suspect 32/64 bit incompatibilities. Something went very wrong. Are you building 64 app? Can you try to build SDL with your compiler and then test your app with custom SDL?