IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Demineur erreur de segmentation.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Par défaut Demineur erreur de segmentation.
    Salut,

    Je code un démineur en console, et j'utilise la récursivité (en taous cas j'essaye), j'ai une erreur de segmentation dans la fonction qui dévoile les cases, je la post ici.
    J'utilise 2 tableaux, pour l'instant ils sont initialisés normalement donc je dois tester à chaque fois les bords, les coins et les côtés pour éviter justement ce genre d'erreur, mais je ne comprend pas pourquoi ça ne fonctionne pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    void devoileCase(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE], int y, int x)
    {
    	if(tableauMine[y][x] == 0)
    	{
    		tableauJeu[y][x] = VIDE;
     
    		if(x == 0 && y == 0)
    		{
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    		}
    		else if(x == 0 && (y > 0 && y < TAILLE))
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    		}
    		else if(x == 0 && y == TAILLE)
    		{
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    		}
    		else if((x > 0 && x < TAILLE) && y == 0)
    		{
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			devoileCase(tableauJeu, tableauMine, y+1, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    		}
    		else if((x > 0 && x < TAILLE) && y == TAILLE)
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    		}
    		else if(x == TAILLE && (y > 0 && y < TAILLE))
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    		}
    		else if(x == TAILLE && y == 0)
    		{
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    		}
    		else if(x == TAILLE && y == TAILLE)
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    		}
    		else
    		{
    			devoileCase(tableauJeu, tableauMine, y-1, x-1);
    			devoileCase(tableauJeu, tableauMine, y-1, x);
    			devoileCase(tableauJeu, tableauMine, y-1, x+1);
    			devoileCase(tableauJeu, tableauMine, y, x-1);
    			devoileCase(tableauJeu, tableauMine, y, x+1);
    			devoileCase(tableauJeu, tableauMine, y+1, x-1);
    			devoileCase(tableauJeu, tableauMine, y+1, x);
    			devoileCase(tableauJeu, tableauMine, y+1, x+1);
    		}
    	}
     
    	if(tableauMine[y][x] == 1)	tableauJeu[y][x] = '1';
    	if(tableauMine[y][x] == 2)	tableauJeu[y][x] = '2';
    	if(tableauMine[y][x] == 3)	tableauJeu[y][x] = '3';
    	if(tableauMine[y][x] == 4)	tableauJeu[y][x] = '4';
    	if(tableauMine[y][x] == 5)	tableauJeu[y][x] = '5';
    	if(tableauMine[y][x] == 6)	tableauJeu[y][x] = '6';
    	if(tableauMine[y][x] == 7)	tableauJeu[y][x] = '7';
    	if(tableauMine[y][x] == 8)	tableauJeu[y][x] = '8';
    	if(tableauMine[y][x] == 9)	tableauJeu[y][x] = '9';
    }
    Merci.

  2. #2
    Membre très actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Par défaut
    Bonjour,
    tu peux beaucoup simplifier ta fonction en englobant tout son contenu dans un test pour savoir si tu es dans le tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void devoileCase(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE], int y, int x)
    {
    	if (x >= 0 && x <TAILLE && y >= TAILLE && y < TAILLE) {
    		/* Dévoiler la case */
    	}
    }
    Comme ça tu n'as pas besoin de particulariser ton code si tu te trouves au bord du damier. Tu auras plus de facilité à trouver ton erreur de seg si elle y est toujours. Et dans ce cas, n'hésite pas à utiliser valgrind pour trouver ton bug (ou gdb, mais c'est moins simple).

    Plus précisément, concernant ton erreur, je sui à peu près sûr que tu as oublié un cas, ou que tu t'es trompé en traitant un cas. Donc si tu les supprime tous, ça devrait marcher .

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Par défaut
    Oui mais si j'execute ce code, je testerais les cases qu'il y a à l'interieur du tableau, donc les bords et les coins je les oublies, et ils ne sont jamais dévoilé ??

    Sinon ce que j'avais pensé à faire c'est initialiser tous les bords et les coins en case vide et par conséquent je peux utiliser ta méthode.

  4. #4
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Sinon, ceci devrait fonctionner, non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    if (x > 0)
    {
        if (y > 0)
             devoileCase(tableauJeu, tableauMine, y-1, x-1);
     
        devoileCase (tableauJeu, tableauMine, y, x-1);
     
        if (y < TAILLE)
             devoileCase(tableauJeu, tableauMine, y+1, x-1);
    }
     
    if (x < TAILLE)
    {
        if (y > 0)
             devoileCase(tableauJeu, tableauMine, y-1, x+1);
     
        devoileCase (tableauJeu, tableauMine, y, x+1);
     
        if (y < TAILLE)
             devoileCase(tableauJeu, tableauMine, y+1, x+1);
    }
     
    if (y > 0)
    {
        devoileCase (tableauJeu, tableauMine, y-1, x);
    }
     
     
    if (y < TAILLE)
    {
        devoileCase (tableauJeu, tableauMine, y+1, x);
    }

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Par défaut
    Non ce code ne fonctionne pas, toujours une erreur de segmentation, j'ai regardé ton code et il n'y as pas l'air d'avoir d'erreur dans les appels de fonctions donc la non plus je ne sais pas d'ou ça viens.

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Par défaut
    @ezano ajouter une ligne autour, ça devrait marcher très bien. C'est pas optimal côté occupation mémoire, mais c'est pas monstrueusement grave dans ce genre de cas...

    En revanche, si on reprend mon algo, que je détaille un peu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    dévoiler(x, y)
        si dans le damier et non dévoilée
            découvrir(x,y)
            si mine alors
                boom
            sinon si nombre nul alors
                pour chaque case(X,Y) autour
                    dévoiler(X,Y)
                    /* Les cases autour sont (x+1,y), (x+1,y+1), (x,y+1) ... 8 en tout */
    (X,Y) c'est les coordonnées d'une case autour de celle qu'on était en train de dévoiler et découvrir c'est la fonction qui te fait afficher ce qu'il y avait dans la case.
    ma solution devrait fonctionner elle aussi, exemple, on considère le damier suivant :

    On suppose que rien n'est découvert. Si on clique sur la case de coordonnées (3, 0) (abscisse, ordonnée).
    On considère qu'on tourne dans le sens des aiguilles d'une montre à partir de la case à droite, on obtient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    dévoiler(3,0)  /* Nombre non nul donc on découvre autour */
        découvrir(3,0)
        dévoiler(4,0) /* Nombre non nul donc on découvre autour */
            découvrir(4,0) 
            dévoiler(5,0)  /* Nombre nul donc on ne découvre pas autour */
                découvrir(5,0)
            dévoiler(5,1)
                découvrir(5,1)
            dévoiler(4,1)
                découvrir(4,1)
            dévoiler(3,1)
                découvrir(3,1)
            dévoiler(3,0) /* rien ne se passe car déjà découverte */
            dévoiler(3,-1) /* rien ne se passe car hors damier */
            dévoiler(4,-1) /* rien ne se passe car hors damier */
            dévoiler(5,-1) /* rien ne se passe car hors damier */
        dévoiler(4,1) /* rien ne se passe car déjà découverte */
        dévoiler(3,1) /* rien ne se passe car déjà découverte */
        dévoiler(2,1)
            découvrir(2,1)
        dévoiler(2,0)
            découvrir(2,0)
        dévoiler(2,-1) /* rien ne se passe car hors damier */
        dévoiler(3,-1) /* rien ne se passe car hors damier */
        dévoiler(4,-1) /* rien ne se passe car hors damier */
    Sinon pour tes erreurs de ség, compile avec les informations de débogage (flag -g de gcc) et utilise valgrind.

  7. #7
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    @-ezano-
    Ton code est illogique dans ses tests :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void devoileCase(char tableauJeu[TAILLE][TAILLE], char tableauMine[TAILLE][TAILLE], int y, int x)
    {
    	if(tableauMine[y][x] == 0)
    	{
    		tableauJeu[y][x] = VIDE;
     
    		if(x == 0 && y == 0)
    ....
    		else if(x == 0 && (y > 0 && y < TAILLE))
    ....
    D'après la dernière ligne montrée ici où on teste y > 0 et y < TAILLE (et plus loin dans le code, on teste x < TAILLE et x > 0), on peut entrer dans cette fonction avec y (et/ou x) négatif ou y (et/ou x) égal à TAILLE.

    Dans ces cas, tableauMine[y][x] == 0 accède et tableauJeu[y][x] = VIDE modifie des "éléments" hors des tableaux -> plantage.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreurs de segmentation !
    Par anti-conformiste dans le forum Applications et environnements graphiques
    Réponses: 16
    Dernier message: 18/10/2005, 11h11
  2. Erreur de segmentation
    Par Trunks dans le forum C
    Réponses: 3
    Dernier message: 06/10/2005, 18h28
  3. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    Réponses: 5
    Dernier message: 08/09/2005, 13h42
  4. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 14h25
  5. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 11h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo