Partage
  • Partager sur Facebook
  • Partager sur Twitter

[SDL] Segmentation Fault c'est quoi ?

    7 février 2006 à 15:28:35

    Salut !

    Je suis en train d'apprendre à me servir de la SDL, donc j'essaye de bien comprendre toutes les bases, mais j'ai déjà des problèmes. Alors, j'ai construit un code qui permet simplement d'afficher un bmp à l'écran, et il marche, voyez plutôt:

    #include <stdio.h>
    #include <stdlib.h>

    #include <SDL/SDL.h>


    void init_SDL();
    void quit_SDL();

    SDL_Surface *ecran;

    int main(int argc, char *argv[])
    {


            init_SDL();

            SDL_Rect rect; // Source
        SDL_Rect dest; // Destination
        SDL_Event event; // Evenements

        rect.x=0;
        rect.y=0;
        rect.w=200;
        rect.h=200; // L'image fait 200x200

        dest.x=260;
        dest.y=260;
        dest.w=200;
        dest.h=200;

            SDL_Surface *sPerso = SDL_LoadBMP("perso.bmp");

            while( 1 )
            {

                // Tant qu'il y a des evennements
            while(SDL_PollEvent(&event))
            {
                // Si c'est un message SDL_QUIT
                if(event.type==SDL_QUIT)
                {
                    quit_SDL();
                }
                // Si c'est un évennement clavier
                else if(event.type==SDL_KEYDOWN)
                {
                    // Si c'est la touche Echap
                    if(event.key.keysym.sym==SDLK_ESCAPE)
                        quit_SDL();
                }
            }

                /* Affichage */
                SDL_BlitSurface( sPerso, &rect, ecran, &dest);

                /* Flip */
                SDL_Flip( ecran );

            }

            return 0;

    }

    // Fonction qui initialise SDL
    void init_SDL()
    {

        SDL_Init(SDL_INIT_VIDEO);
        ecran = SDL_SetVideoMode(800,
                                 600,
                                 32,
                                 SDL_HWSURFACE|
                                 SDL_DOUBLEBUF|
                                 SDL_FULLSCREEN);
        SDL_ShowCursor(0);

    }

    // Fonction pour quitter
    void quit_SDL()
    {

        SDL_FreeSurface( ecran );
        SDL_ShowCursor(1);
        SDL_Quit();
        exit(0);

    }


    Je me suis appuyé principalement sur ce cours.

    Bref, ça marche, mais le fait qu'il y ait une variable globale ça me plaît pas trop, même si on peut faire avec. J'ai donc essayé de modifier tout ça. Comme on gère la surface comme un pointeur, il suffit de passer le pointeur en paramètre aux fonctions et ça marchera !

    Voila donc le code que j'ai fais :

    #include <stdio.h>
    #include <stdlib.h>

    #include <SDL/SDL.h>


    void init_SDL( SDL_Surface *back_surface_a_initialiser );
    void quit_SDL( SDL_Surface *back_surface_a_liberer );

    int main(int argc, char *argv[])
    {

            SDL_Surface *ecran;

            init_SDL( ecran );

            SDL_Rect rect; // Source
        SDL_Rect dest; // Destination
        SDL_Event event; // Evenements

        rect.x=0;
        rect.y=0;
        rect.w=200;
        rect.h=200; // L'image fait 200x200

        dest.x=260;
        dest.y=260;
        dest.w=200;
        dest.h=200;

            SDL_Surface *sPerso = SDL_LoadBMP("perso.bmp");

            while( 1 )
            {

                // Tant qu'il y a des evennements
            while(SDL_PollEvent(&event))
            {
                // Si c'est un message SDL_QUIT
                if(event.type==SDL_QUIT)
                {
                    quit_SDL( ecran );
                }
                // Si c'est un évennement clavier
                else if(event.type==SDL_KEYDOWN)
                {
                    // Si c'est la touche Echap
                    if(event.key.keysym.sym==SDLK_ESCAPE)
                        quit_SDL( ecran );
                }
            }

                /* Affichage */
                SDL_BlitSurface( sPerso, &rect, ecran, &dest);

                /* Flip */
                SDL_Flip( ecran );

            }

            return 0;

    }

    // Fonction qui initialise SDL
    void init_SDL( SDL_Surface *back_surface_a_initialiser )
    {

        SDL_Init(SDL_INIT_VIDEO);
        back_surface_a_initialiser = SDL_SetVideoMode(800,
                                                      600,
                                                      32,
                                                      SDL_HWSURFACE|
                                                      SDL_DOUBLEBUF|
                                                      SDL_FULLSCREEN);
        SDL_ShowCursor(0);

    }

    // Fonction pour quitter
    void quit_SDL( SDL_Surface *back_surface_a_liberer )
    {

        SDL_FreeSurface( back_surface_a_liberer );
        SDL_ShowCursor(1);
        SDL_Quit();
        exit(0);

    }


    Mais cette fois, le programme se lance, mais rien ne s'affiche à l'écran. (je peux quand même quitter le programme avec Echap)

    Par contre, il y a un fichier stderr.txt qui se créé et qui contient

    Citation : stderr.txt

    Fatal signal: Segmentation Fault (SDL Parachute Deployed)



    Que signifie cette erreur, et qu'est ce qui ne fonctionne pas dans mon code ?

    Merci !
    • Partager sur Facebook
    • Partager sur Twitter
      7 février 2006 à 15:47:19

      Je pense que le problème se situe dans la fonction init_SDL.

      Tu modifies le pointeur de l'argument, mais je ne suis pas sûr que ca modifie effectivement l'argument (question de copie par valeur).

      Pourrais-tu essayer comme ca ? (je ne peut pas tester mon code pour l'instant)

      void init_SDL()
      {
          SDL_surface *root;
          SDL_Init(SDL_INIT_VIDEO);
          root = SDL_SetVideoMode(800,
                                                        600,
                                                        32,
                                                        SDL_HWSURFACE|
                                                        SDL_DOUBLEBUF|
                                                        SDL_FULLSCREEN);
          SDL_ShowCursor(0);
          return root;
      }


      et dans le corps :
      SDL_Surface *ecran;
      ecran = SDL_init();
      • Partager sur Facebook
      • Partager sur Twitter
        7 février 2006 à 16:04:23

        Tu veux dire que la surface serait copiée et ensuite modifiée dans la fonction, mais alors ça ne modifirait en rien la surface originale ?

        Hum, c'est pas cool ça, pourtant on passe l'adresse de la surface en paramètre, ça devrait pas se copier... ?

        Enfin, j'ai essayé ce que tu dis, mais ça ne fonctionne pas. Voila le code que j'ai utilisé :

        SDL_Surface init_SDL()
        {

            SDL_Surface *root;
            SDL_Init(SDL_INIT_VIDEO);
            root = SDL_SetVideoMode(800,
                                    600,
                                    32,
                                    SDL_HWSURFACE|
                                    SDL_DOUBLEBUF|
                                    SDL_FULLSCREEN);
            SDL_ShowCursor(0);

            return root;
        }

        /* Dans le corps */
        SDL_Surface *ecran;
        ecran = init_SDL();


        J'ai ces deux erreurs:

        Citation : code::blocks

        /* Sur la ligne du return */
        error: incompatible types in return

        /* Sur la ligne de ecran = init_SDL() */
        error: incompatible types in assignement



        Mais pourquoi on renvoie l'adresse de root, enfin on fais :

        ecran (donc l'adresse sur laquelle pointe ecran) = init_SDL(); (on retourne l'adresse de root, mais cette variable va être détruite à la fermeture de la fonction non ? donc finalement rien ne sera initialisé)

        Il n'y a pas un moyen pour empêcher le phénomène de copie ?
        • Partager sur Facebook
        • Partager sur Twitter
          7 février 2006 à 16:24:14

          Salut
          dans la declaration de ta fonction tu met SDL_Surface init_SDL()
          donc tu renvoie une SDL_Surface pas un pointeur vers cet surface
          et apres tu met
          screen (qui est un pointeur) = la fonction (qui n'est pas un pointeur)
          d'ou les erreurs.

          Essaie avec cet declaration pour ta fonction:
          SDL_Surface* init_SDL()
          • Partager sur Facebook
          • Partager sur Twitter
            7 février 2006 à 16:47:11

            Hey, avec ça ça marche !! Je n'avais pas bien saisi le fait que la fonction renvoie un pointeur, enfin comme le pointeur prend le type de la variable sur la quelle il pointe, j'oublie toujours de rajouter l'étoile dans la fonction...

            Sinon, pour la fonction qui quitte SDL, est ce que tout va bien ?

            void quit_SDL( SDL_Surface *back_surface_a_liberer )
            {

                SDL_FreeSurface( back_surface_a_liberer );
                SDL_ShowCursor(1);
                SDL_Quit();
                exit(0);
            }

            /* Et elle est appelée comme ça : */
            quit_SDL( ecran );


            Est ce que la back surface "ecran" est bien libérée, n'y a t il pas un problème de copie comme dans l'ancienne fonction d'initialisation ?

            Je pense que non, mais on ne sait jamais !
            • Partager sur Facebook
            • Partager sur Twitter

            [SDL] Segmentation Fault c'est quoi ?

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown