The following program is ending with status 3 every time I'm starting it.
#include "amr-0-1.h"
#include "SDL_sys.c"
int screen_w=351, screen_h=234;
int ss_w=screen_w*(5/9), ss_h=screen_h*(11/19);
int m_w=screen_w*(7/27), m_h=screen_h*(175/234);
int g_w=screen_w*(100/351), g_h=screen_h*(2/9);
int mo_w=screen_w*(29/117), mo_h=screen_h*(1/13);
int ss_mo_w=screen_w*(17/117), ss_mo_h=screen_h*(4/117);
int p_d=32, border=2;
SDL_Surface *screen = NULL; //Fenetre principale
SDL_Surface *m = NULL; //Surface du menu
SDL_Surface *mo = NULL; //Surface d'une option menu
SDL_Surface *ss = NULL; //Surface de la zone d'écran secondaire
SDL_Surface *ss_mo = NULL; //Surface d'une option du sous-menu
SDL_Surface *p = NULL; //Surface destinée à accueillir l'image utilisateur
SDL_Rect c_m;
SDL_Rect c_mo;
SDL_Rect c_ss;
SDL_Rect c_ss_mo;
SDL_Rect c_p;
SDL_Rect c_screen;
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Erreur d'initialisation de la SDL");
exit(EXIT_FAILURE);
}
SGI_Init(1, screen, 351, 234, NULL, 0, 0, &c_screen); //Écran principal
SGI_Init(0, m, m_w, m_h, screen, 39, 58, &c_m); //Menu
SGI_Init(0, ss, ss_w, ss_h, screen, 156, 78, &c_ss); //Surface d'écran secondaire
pause();
SDL_Quit();
return EXIT_SUCCESS;
}
According to my research, status 3 stand for 'SegFault', so it's an allocation problem with one (or more) of the SDL' surface. Here is how I allocate the surface:
#include "amr-0-1.h"
void pause()
{
int continuer = 1;
SDL_Event event;
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
}
}
}
int SGI_Init(int command, SDL_Surface *child, int child_w, int child_h, SDL_Surface *mother, int x, int y, SDL_Rect* cursor)
{
if(command)
{
child = SDL_SetVideoMode(child_w, child_h, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
return 1;
}
else if(!command)
{
child = SDL_CreateRGBSurface(SDL_HWSURFACE, child_w, child_h, 32, 0,0,0,0);
SDL_FillRect(child, cursor, SDL_MapRGB(mother->format,255,255,255));
cursor->x=x;
cursor->y=y;
SDL_BlitSurface(child, NULL, mother, cursor);
SDL_Flip(mother);
return 1;
}
else
{
return 0;
}
}
The header amr-0-1.h:
#include <stdlib.h>
#include <stdio.h>
#include <SDL.h>
void pause();
int SGI_Init(int command, SDL_Surface *child, int child_w, int child_h, SDL_Surface *mother, int x, int y, SDL_Rect* cursor);
I can't find why my allocation is incorrect.
I'm using SDL 1.2 and CodeBlocks 17.12, also I'm a noob and I'm French, so please be patient I'm slow!
The immediate SEGFAULT is probably caused by
SDL_FillRect(child, cursor, SDL_MapRGB(mother->format,255,255,255));
The reason behind this is answered in the comment of keltar:
In this line:
SGI_Init(1, screen, 351, 234, NULL, 0, 0, &c_screen);
you pass in screen
in order to initialize it.
What happens here is that the value of screen
is copied into the local variable child
.
You then modify child
, but this happens to the copy of screen
, screen
itself stays the same.
You are probably confused by the fact that screen
is a pointer.
However, you want to modify the pointer, and therefore you require a pointer to a pointer like this:
int SGI_Init(int command, SDL_Surface **child, int child_w, int child_h, SDL_Surface *mother, int x, int y, SDL_Rect* cursor)
{
if(command)
{
*child = SDL_SetVideoMode(child_w, child_h, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
return 1;
}
else if(!command)
{
*child = SDL_CreateRGBSurface(SDL_HWSURFACE, child_w, child_h, 32, 0,0,0,0);
SDL_FillRect(*child, cursor, SDL_MapRGB(mother->format,255,255,255));
cursor->x=x;
cursor->y=y;
SDL_BlitSurface(*child, NULL, mother, cursor);
SDL_Flip(mother);
return 1;
}
else
{
return 0;
}
}
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Erreur d'initialisation de la SDL");
exit(EXIT_FAILURE);
}
SGI_Init(1, &screen, 351, 234, NULL, 0, 0, &c_screen); //Écran principal
printf("%p\n", screen);
SGI_Init(0, &m, m_w, m_h, screen, 39, 58, &c_m); //Menu
SGI_Init(0, &ss, ss_w, ss_h, screen, 156, 78, &c_ss); //Surface d'écran secondaire
pause();
SDL_Quit();
return EXIT_SUCCESS;
}
But why not just return the new SDL_Surface
like so:
SDL_Surface* SGI_Init(int command, int child_w, int child_h, SDL_Surface *mother, int x, int y, SDL_Rect* cursor)
{
if(command)
{
return SDL_SetVideoMode(child_w, child_h, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
}
else if(!command)
{
SDL_Surface* child = SDL_CreateRGBSurface(SDL_HWSURFACE, child_w, child_h, 32, 0,0,0,0);
SDL_FillRect(child, cursor, SDL_MapRGB(mother->format,255,255,255));
cursor->x=x;
cursor->y=y;
SDL_BlitSurface(child, NULL, mother, cursor);
SDL_Flip(mother);
return child;
}
else
{
return 0;
}
}
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Erreur d'initialisation de la SDL");
exit(EXIT_FAILURE);
}
screen = SGI_Init(1, 351, 234, NULL, 0, 0, &c_screen); //Écran principal
printf("%p\n", screen);
m = SGI_Init(0, m_w, m_h, screen, 39, 58, &c_m); //Menu
ss = SGI_Init(0, ss_w, ss_h, screen, 156, 78, &c_ss); //Surface d'écran secondaire
pause();
SDL_Quit();
return EXIT_SUCCESS;
}
There are a few things in your code that might cause undefined behaviour, like
SDL_Rect c_m;
SDL_Rect c_mo;
SDL_Rect c_ss;
...
declare the variables, but you never initialize them, you just pass them in to functions as parameters. If one of them is ever read before initialization, it inflicts undefined behaviour.
Even so, there are a lot of code smells in there, the most striking one is obvious by the command
parameter: Your SDI_Init
function does two entirely different things. You should try to stick to the single responsibility principle and split the function up into 2 functions - one per task. If you want to stick to your design, at least resort back to using an appropriate enum
for command
...