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 :

probleme fonction d'initialisation


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    cnam
    Inscrit en
    Avril 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Liban

    Informations professionnelles :
    Activité : cnam
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2013
    Messages : 14
    Par défaut probleme fonction d'initialisation
    bonsoir mes amis

    je suis en train d'écrire un programme de démineur il est pas complet encore mon problème est avec la fonction init qui initialise le tableau t de l ligne et c colonne avec m mines repartie aléatoirement
    erreur segmentation fault apparaît au niveau de cette fonction je ne peut pas détecter mon erreur
    peut être vous pouvez m'aider a la trouver
    merci beaucoup

    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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <conio.h>
    #include <windows.h>
    #define droite 77
    #define gauche 75
    #define haut 72
    #define bas 80
    #define drapeau 32
    #define revele 13
    typedef struct
    {
        int x,y;
    } mycoord;
    void gotoligcol(int lig, int col)
     
    {
        COORD mycoord;
        mycoord.X = col;
        mycoord.Y = lig;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),mycoord);
    }
     
    typedef struct
    {
        char etat;
        int contenue;
    } t_case;
     
    void init(t_case **t,int l,int c,int m)
     
    {
        int mx,my,Compt,x,y;
        for(mx=0; mx<l; mx++)
        {
            for(my=0; my<c; my++)
            {
                t[mx][my].contenue=0;
     
            }
        }
        for (Compt=0; Compt<m; Compt++)
        {
            mx=rand()%l;
            my=rand()%c;
            if(t[mx][my].contenue==0)
            {
                t[mx][my].contenue=-1;
            }
     
            else
            {
                m++;
            }
     
     
        }
        for(mx=0; mx<l; mx++)
        {
            for(my=0; my<c; my++)
            {
                printf("%c",t[mx][my]);
            }
            printf("\n" );
        }
    }
     
    int nb_mines(t_case **t,int i, int j)
    {
        int N;
     
        if (t[i][j].contenue==-1)
        {
            gotoligcol(i,j);
            printf("BOOM, tu as perdu!!\n");
            printf("Voici la grille des mines\n");
     
            for(i=0; i<10; i++)
            {
                for(j=0; j<10; j++)
                {
                    printf("%c",t[i][j].contenue);
                }
                printf("\n" );
            }
            return (0);
        }
        else if (t[i - 1][j].contenue== -1) //compteur indiquant le nombre de mines à proximité
            N++;
        else if (t[i+ 1][j].contenue== -1)
            N++;
        else if (t[i][j -1].contenue== -1)
            N++;
        else if (t[i][j +1].contenue== -1)
            N++;
        else if (t[i - 1][j - 1].contenue == -1)
            N++;
        else if (t[i + 1][j - 1].contenue == -1)
            N++;
        else if (t[i + 1][j + 1].contenue == -1)
            N++;
        else if (t[i - 2][j + 1].contenue == -1)
            N++;
        else
            N= 0;
        printf("%d",N);
        N=0;
    }
     
     
    void main()
    {
        char curseur,choix;
        int i,j,k,niv,l,c,m;
        int N_mine_around;
        t_case **t;
     
        printf("\n\t\t\t\tJEU   DEMINEUR\n\t\t\t\t--------------");
     
        printf("\n\n\t\t\t\t*** NIVEAU *** \n\n\t\t\t\t1.simplifiee\n\t\t\t\t2.normal\n\t\t\t\t3.dur\n\t\t\t\t4.personalisee\n\t\t\n\t\t\t\t\n\t\t\t\tChoix : ");
        scanf("%d",&niv);
        while(niv!=1 && niv!=2 && niv!=3 && niv!=4)     // Choix du niveau
        {
            printf("\nErreur de saisie , veuillez choisir un niveau : ");
            scanf("%d",&niv);
        }
        if (niv==1)
        {
            m=15;
            l=c=10;
        }
        else if (niv==2)
        {
            l=c=15;
            m=45;
        }
        else if (niv==3) // Détermine le nombre de mines par rapport au niveau
        {
            l=c=20;
            m=90;
        }
        else
        {
            printf("donner le nombre des lignes l:");
            scanf("%d",&l);
            printf("donner le nombre des colonnes c:");
            scanf("%d",&c);
            printf("donner le nombre des mines m:");
            scanf("%d",&m);
     
        }
        init(t,l,c,m);
     
    }

  2. #2
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 53
    Par défaut
    Salut
    le code et assez long , commente le bien, et renomme bien les variables par des noms significatifs pour faciliter la détection de l'erreur, et indente le bien, pour une meilleur lisibilité.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t_case **t;// ou est l'allocation??
    tu dois allouer la mémoire pour la variable t.
    à quoi sert contenue, le 0 veut dire quoi et le -1 ??!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for ( Compt = 0 ; Compt < m ; Compt ++ )
         {
               mx = rand() % l ;
               my = rand() % c ;
               if( t[mx][my].contenue == 0 )
               {
    	          t[mx][my].contenue = -1 ;
               }
               else
               {
                   m++ ;
               }
         }
    une condition qui peut ne pas être atteint.
    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
    int nb_mines(t_case **t,int i, int j)
    { 
        int N;
        if ( t[i][j].contenue == - 1 )
        {
            gotoligcol(i,j);
            printf("BOOM, tu as perdu!!\n");
            printf("Voici la grille des mines\n");
     
            for(i=0;i<10;i++)
           {
               for(j=0;j<10;j++)
               {
                printf("%c",t[i][j].contenue);
               }
              printf("\n" );
            }
            return (0);
        }
        else if (t[i - 1][j].contenue== -1) //compteur indiquant le nombre de mines à proximité
            N++;
        else if (t[i+ 1][j].contenue== -1)
            N++;
        else if (t[i][j -1].contenue== -1)
            N++;
        else if (t[i][j +1].contenue== -1)
            N++;
        else if (t[i - 1][j - 1].contenue == -1)
            N++;
        else if (t[i + 1][j - 1].contenue == -1)
            N++;
        else if (t[i + 1][j + 1].contenue == -1)
            N++;
        else if (t[i - 2][j + 1].contenue == -1)
            N++;
        else
            N= 0;
        printf("%d",N);
        N=0;
    }
    ou est la valeur de retour de cette fonction si le bloc if n'est pas exécuté??

  3. #3
    Membre expérimenté Avatar de moins1
    Homme Profil pro
    Autre
    Inscrit en
    Février 2013
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Autre
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 85
    Par défaut
    Citation Envoyé par b-med Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t_case **t;// ou est l'allocation??
    tu dois allouer la mémoire pour la variable t.
    Pour un démineur aussi bien déclarer un tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t_case t[TAILLE][TAILLE]
    Petite remarque, habituellement on écrit les constantes en majuscule.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #define DROITE 77
    #define GAUCHE 75
    #define HAUT 72
    #define BAS 80
    #define DRAPEAU 32
    #define REVELE 13

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    J'ai indenté le code pour une meilleur lisibilité

    Pour savoir d'où vient l'erreur de segmentation, je recommande de passer l'exécutable dans http://www.developpez.net/forums/d12...light=drmemory

  5. #5
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Bonjour,

    Je suis du meme avis que b-med.
    Tu demandes a l'utilisateur de rentrer ses propres valeurs pour les lignes et colonnes => allocation dynamique de mémoire.
    Mais tu ne fais pas de malloc pour réserver l'espace pour ton tableau.
    Du coup, segmentation fault.

  6. #6
    Membre averti
    Homme Profil pro
    cnam
    Inscrit en
    Avril 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Liban

    Informations professionnelles :
    Activité : cnam
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2013
    Messages : 14
    Par défaut
    Citation Envoyé par b-med Voir le message
    Salut
    le code et assez long , commente le bien, et renomme bien les variables par des noms significatifs pour faciliter la détection de l'erreur, et indente le bien, pour une meilleur lisibilité.

    salut tu a bien raison avec ça,je suis en train de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t_case **t;// ou est l'allocation??
    tu dois allouer la mémoire pour la variable t.
    j'ai essayé différentes allocations mais aucun ne marche j’espère que j'alloc incorrectement
    je sais que je dois allouée deux fois une première pour le pointeur double et l'autre pour chaque élément du pointeur qui doit contenir une variable de type t_case définie dans la structure

    Citation Envoyé par b-med Voir le message
    à quoi sert contenue, le 0 veut dire quoi et le -1 ??!

    le -1 la case contenue un mine
    et le zero la case vide

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for ( Compt = 0 ; Compt < m ; Compt ++ )
         {
               mx = rand() % l ;
               my = rand() % c ;
               if( t[mx][my].contenue == 0 )
               {
    	          t[mx][my].contenue = -1 ;
               }
               else
               {
                   m++ ;
               }
         }
    une condition qui peut ne pas être atteint.
    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
    int nb_mines(t_case **t,int i, int j)
    { 
        int N;
        if ( t[i][j].contenue == - 1 )
        {
            gotoligcol(i,j);
            printf("BOOM, tu as perdu!!\n");
            printf("Voici la grille des mines\n");
     
            for(i=0;i<10;i++)
           {
               for(j=0;j<10;j++)
               {
                printf("%c",t[i][j].contenue);
               }
              printf("\n" );
            }
            return (0);
        }
        else if (t[i - 1][j].contenue== -1) //compteur indiquant le nombre de mines à proximité
            N++;
        else if (t[i+ 1][j].contenue== -1)
            N++;
        else if (t[i][j -1].contenue== -1)
            N++;
        else if (t[i][j +1].contenue== -1)
            N++;
        else if (t[i - 1][j - 1].contenue == -1)
            N++;
        else if (t[i + 1][j - 1].contenue == -1)
            N++;
        else if (t[i + 1][j + 1].contenue == -1)
            N++;
        else if (t[i - 2][j + 1].contenue == -1)
            N++;
        else
            N= 0;
        printf("%d",N);
        N=0;
    }
    ou est la valeur de retour de cette fonction si le bloc if n'est pas exécuté??
    cette fonction doit être exécutée pour chaque case elle teste les case entourant le case désirée et donne le nombre de mine adjacent a cette case


    Citation Envoyé par moins1 Voir le message
    Pour un démineur aussi bien déclarer un tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t_case t[TAILLE][TAILLE]
    Petite remarque, habituellement on écrit les constantes en majuscule.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #define DROITE 77
    #define GAUCHE 75
    #define HAUT 72
    #define BAS 80
    #define DRAPEAU 32
    #define REVELE 13
    bonsoir
    j'ai une exigence pour utiliser la structure t_case avec un pointeur double **t

  7. #7
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 53
    Par défaut
    Salut,
    pour l'allocation, tu dois faire quelque chose comme ça, c'est juste une idée vérifie bien le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    t_case **t;
    t = (t_case **)malloc(sizeof( *t_case ) * nbrColonne);
    for(int i = 0 ; i < nbrColonne ; i++)
    {
    	t[i] = (t_case *)malloc(sizeof(t_case) * nbrLigne);
    }
    pour cette fonction, croie moi, il ne marchera pas, il y a pas de valeur de retour si le bloc if ne s'exécute 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
    int nb_mines(t_case **t,int i, int j)
    { 
        int N;
        if ( t[i][j].contenue == - 1 )
        {
            gotoligcol(i,j);
            printf("BOOM, tu as perdu!!\n");
            printf("Voici la grille des mines\n");
     
            for(i=0;i<10;i++)
           {
               for(j=0;j<10;j++)
               {
                printf("%c",t[i][j].contenue);
               }
              printf("\n" );
            }
            return (0);
        }
        else if (t[i - 1][j].contenue== -1) //compteur indiquant le nombre de mines à proximité
            N++;
        else if (t[i+ 1][j].contenue== -1)
            N++;
        else if (t[i][j -1].contenue== -1)
            N++;
        else if (t[i][j +1].contenue== -1)
            N++;
        else if (t[i - 1][j - 1].contenue == -1)
            N++;
        else if (t[i + 1][j - 1].contenue == -1)
            N++;
        else if (t[i + 1][j + 1].contenue == -1)
            N++;
        else if (t[i - 2][j + 1].contenue == -1)
            N++;
        else
            N= 0;
        printf("%d",N);
        N=0;
    //ou est la valeur de retour dans les blocs esle if ou ici
    }
    l'instruction suivante n'est pas valide pur cette fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int nbrMine = nb_mines( t , i ,   j )  ;
    tu sais pas ce que la fonction va retourner. Je vais dire encore, un retour est manquant

  8. #8
    Membre averti
    Homme Profil pro
    cnam
    Inscrit en
    Avril 2013
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Liban

    Informations professionnelles :
    Activité : cnam
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2013
    Messages : 14
    Par défaut
    bonsoir les amies

    j'ai arriver a ce code beaucoup des problème résolue mais il me reste quelque truc ,est ce que vous pouvez m'aider
    merci beaucoup

    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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <conio.h>
    #include <windows.h>
    #define droite 77
    #define gauche 75
    #define haut 72
    #define bas 80
    #define drapeau 32
    #define revele 13
    typedef struct
    {
    int x,y;
    }mycoord;
     
    void gotoligcol(int lig, int col)
     
    {  COORD mycoord;
        mycoord.X = col;
       mycoord.Y = lig;
       SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),mycoord);
    }
     
    typedef struct
    {
        int etat;
        int contenue;
    }t_case;
     
    void init(t_case **T,int L,int C,int M)
     
        {int Compt,X,Y,i,j;
    T=(t_case **)malloc(L*sizeof(t_case*));
    for(i=0;i<L+1 ;i++)
    T[i]=(t_case*)malloc(L*C*sizeof(t_case));
     
        for(i=0;i<L+1 ;i++)
    for(j=0;j<C+1 ;j++)
    {T[i][j].contenue=0;
     T[i][j].etat=0;
     
        }
     
     
     while(M)
        {
            X=rand()%L;//random(m);
            Y=rand()%C;//random(n);
     
              if(T[X][Y].contenue==0)
            {
                T[X][Y].contenue=-1;
                M--;
            }
            }
     
    }
     
    int verifMine(t_case **T,int x, int y,int L,int C) //vérifie dans le tableau mine si on tombe sur une mine ou non
    {
     
     
     
    int N_mine_around=0;
        if (T[x][y].contenue == -1)
        {
            system("cls");
            gotoligcol(x,y);
            printf("BOOM, tu as perdu!!\n");
            printf("Voici la grille des mines\n");
     
            for(x=0;x<L;x++)
           {
               for(y=0;y<C;y++)
               {
                printf("%c",T[x][y].contenue);
               }
              printf("\n" );
            }
            return (0);
        }
        else if (T[x - 1][y].contenue== -1) //compteur indiquant le nombre de mines à proximité
            N_mine_around++;
        else if (T[x+ 1][y].contenue== -1)
            N_mine_around++;
        else if (T[x][y -1].contenue== -1)
            N_mine_around++;
        else if (T[x][y +1].contenue== -1)
            N_mine_around++;
        else if (T[x - 1][y - 1].contenue== -1)
            N_mine_around++;
        else if (T[x + 1][y - 1].contenue == -1)
            N_mine_around++;
        else if (T[x + 1][y + 1].contenue == -1)
            N_mine_around++;
        else if (T[x - 2][y + 1].contenue == -1)
            N_mine_around++;
        else
            N_mine_around = 0;
        printf("%d", N_mine_around);
        N_mine_around=0;
    }
     
    int jouer(t_case **T,int L,int C) // fonction pour déplacer le curseur dans le tableau avec z,q,s et d
    {
    int x=1,y=1;
    int curseur;
    gotoligcol(x,y);
    while(curseur!=27){
    curseur=getch();
     
     
    switch(curseur)
    {t_case **T;
     
                   case  haut: x=x-1;y=y;gotoligcol(x,y);break;
                   case bas: x=x+1;y=y;gotoligcol(x,y);break;
                   case gauche : x=x;y=y-1;gotoligcol(x,y);break;
                   case droite :x=x;y=y+1;gotoligcol(x,y);break;
                   case drapeau :if (T[x][y].etat==0)printf("219");else if (T[x][y].etat==1)printf("%d",219);gotoligcol(x,y); /* pose ou enlève un drapeau */break;
                    case revele :if (T[x][y].etat == 0)
    {
                            //printf(" ");
                            gotoligcol(x,y);
                            verifMine(T,x,y,L,C);
                            break;
                   }
                            else
                            gotoligcol(x,y);
                            break;
                  // getch();
     
    }
                     if (x>L){
                     x=x-1 ; gotoligcol(x,y);}
                    else if (y>C){
                     y=y-1 ; gotoligcol(x,y);}   // Pour ne pas sortir du tableau de jeu !!
                    else if (y<1){
                    y=y+1 ; gotoligcol(x,y);}}
    }
     
     
     
     
    void main()
    {
     
    int i,j,k,niv,l,c,m,n=0;
    int N_mine_around;
    t_case **T;
     
       printf("\n\t\t\t\tJEU   DEMINEUR\n\t\t\t\t--------------");
     
       printf("\n\n\t\t\t\t*** NIVEAU *** \n\n\t\t\t\t1.simplifiee\n\t\t\t\t2.normal\n\t\t\t\t3.dur\n\t\t\t\t4.personalisee\n\t\t\n\t\t\t\t\n\t\t\t\tChoix : ");
       scanf("%d",&niv);
       while(niv!=1 && niv!=2 && niv!=3 && niv!=4)     // Choix du niveau
       {
        printf("\nErreur de saisie , veuillez choisir un niveau : ");
        scanf("%d",&niv);
        }
         if (niv==1)
        {
        m=15;
        l=10;c=10;
        }
        else if (niv==2)
        {
            l=15;c=15;
        m=45;
        }
        else if (niv==3) // Détermine le nombre de mines par rapport au niveau
        {l=20;c=20;
        m=90;
     
        }
        else
        {printf("donner le nombre des lignes l:");
        scanf("%d",&l);
        printf("donner le nombre des colonnes c:");
        scanf("%d",&c);
        printf("donner le nombre des mines m:");
        scanf("%d",&m);
     
        }
    init(T,l,c,m);
    system("cls");
    jouer(T,l,c);
     
    }

  9. #9
    Membre expérimenté Avatar de moins1
    Homme Profil pro
    Autre
    Inscrit en
    Février 2013
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Autre
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 85
    Par défaut
    À la ligne 108, dans la fonction Jouer(), tu déclares une variable entière "curseur" mais tu ne l'initialise pas alors que tu t'en sers dans la boucle while() ligne 110.

    Toujours dans la fonction Jouer(), la ligne 115 ne sera jamais exécuté.

    Le prototype de la fonction Jouer() nous dit que la fonction retourne un entier alors que ce n'est pas le cas. Même chose pour VerifMine(). Aucun retour non plus dans la fonction main() et le prototype n'est pas bon. Ça devrait être:


    EDIT: Ta fonction Init() malloc sur une copie de l'adresse de **T. Enfin je ne sais pas trop comment expliquer sinon que c'est le même principe que si tu passe une simple variable à une fonction: c'est une copie. Le plus simple serait, dans Init(), de déclarer **T, d'allouer la mémoire et retourner T ou NULL si il y'a un problème.

    Sinon ça devrait être genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Init(t_case ***T, int L, int C, int M)
    {
        *T = malloc(sizeof(**T) * L); // Première dimension
        // Et là la 2 ième dimension
        // code
    }
    Dans ce style là m'semble.

  10. #10
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Ceci dit, il faut se rappeler que chaque allocation dynamique que tu peux éviter, chaque étoile que tu peux éviter, t'évitera une flopée de problème potentiels.

    Typiquement, ta grille sera composée de Ligne lignes et chaque ligne sera composée de Colonne colonnes: tu auras, typiquement, ce que l'on appelle une matrice pleine.

    Dés lors, le fait de travailler avec un tableau contenant directement Ligne fois Colonne élément te fournira strictement le nombre de cases dont tu auras besoin, tout en présentant l'énorme avantage que toutes les cases seront contigües en mémoire.

    La seule chose, c'est que tu ne pourras plus forcément utiliser deux crochets pour accéder à tes cases, mais qu'il faudra utiliser la formule index = num_ligne * Colonne + num_colonne

    La création de ta matrice pourrait alors prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    t_case * initField(int ligne, int colonne){
        t_case * temp = malloc( sizeof(t_case) * ligne * colonne);
        if(temp!=NULL){
            for(int l = 0; l<ligne; ++l){
                for(int c = 0; c<colonne: ++c){
                    temp[l*colonne + c].etat = CACHE; // la case est cachée
                    temp[l*colonne + c].contenue = HASMINE; // et dispose d'une mine (à voir comment tu définis cette valeur ;) )
                }
            }
        }
       return temp;
    }
    Un autre avantage énorme de travailler de la sorte (outre celui d'avoir toutes tes cases contigues en mémoire) est que tu n'as qu'une et une seule allocation dynamique de la mémoire, donc, un et un seul risque que l'allocation dynamique échoue.

    De même, une fois que tu voudra détruire ta matrice, il sufffira d'un et un seul free

    En travaillant avec un t_case **, tu auras un nombre d'allocation dynamique correspondant au nombre de lignes + 1, et donc, un risque d'autant plus grand qu'il y ait une allocation dynamique de la mémoire qui échoue

    De même, pour éviter des fuites mémoires, tu auras, au final, un nombre de free à invoquer correspondant au nombre de lignes + 1

    En ayant (bien que je n'aime pas trop y recourir ) défini des variables globale lignes et colonnes comme correspondant au nombre de ligne et au nombre de colonne de ta grille, tu pourrais très bien (par facilité, pour ne pas avoir à effectuer à chaque fois le calcul par toi meme ) créer une fonction qui renverrait un pointeur sur la case qui correspond à une coordonnée donnée sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    t_case  * obtenirCase(t_case * champs, int l, int c){
        return & champs[l * colones + c];
    }
    voire, pour que tu n'aies pas créé ta structure coordonnée pour rien, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    t_case  * obtenirCase(t_case * champs, mycoord coord){
        return & champs[coord.y * lignes + coord.x];
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    Membre expérimenté Avatar de moins1
    Homme Profil pro
    Autre
    Inscrit en
    Février 2013
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Autre
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 85
    Par défaut
    koala01 +1

    En utilisant un pointeur de pointeur sur un t_case, ce serait aussi possible, avec un second malloc(), d'utiliser les crochets. Bon ça fait deux malloc() et donc deux free() mais c'est pas la fin du monde non plus.

    Pour faire, par exemple, une grille de 8 lignes et 10 colonnes ça pourrait donner quelque chose dans le genre:

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define LIGNE 8
    #define COLONNE 10
     
    struct t_case
    {
        char etat;
        int contenue;
    };
     
    struct t_case **initialiserGrille(struct t_case *tc);
    void AfficherGrille(struct t_case **grille);
     
    int main(void)
    {
        struct t_case *tc = malloc(sizeof(*tc) * LIGNE * COLONNE);
        struct t_case **grille;
        srand(time(NULL));
        if(!tc)
        {
            perror("Erreur: ");
            return 1;
        }
        grille = initialiserGrille(tc);
        if(!grille)
        {
            free(tc);
            return 1;
        }
        AfficherGrille(grille);
        free(tc);
        free(grille);
        return 0;
    }
     
    struct t_case **initialiserGrille(struct t_case *tc)
    {
        struct t_case **grille = malloc(sizeof(*grille) * LIGNE);
        int i, j;
     
        if(grille)
        {
            for(i = 0; i < LIGNE; i++)       // Positionne les pointeurs
                grille[i] = &tc[i * LIGNE];
            for(i = 0; i < LIGNE; i++)       // Initialise les structure
                for(j = 0; j < COLONNE; j++)
                {
                    grille[i][j].contenue = rand() % 2; // Je savais pas quoi mettre
                    grille[i][j].etat = 0;
                }
        }
        return grille;
    }
     
    void AfficherGrille(struct t_case **grille)
    {
        int i, j;
     
        for(i = 0; i < LIGNE; i++)
        {
            for(j = 0; j < COLONNE; j++)
                printf("%d ", grille[i][j].contenue);
            putchar('\n');
        }
    }
    Comme ça les cases sont contiguës et on peut utiliser les crochets.

    Enfin c'est juste une idée hein!


  12. #12
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par moins1 Voir le message
    koala01 +1

    En utilisant un pointeur de pointeur sur un t_case, ce serait aussi possible, avec un second malloc(), d'utiliser les crochets. Bon ça fait deux malloc() et donc deux free() mais c'est pas la fin du monde non plus.
    Ce n'est pas la fin du monde, non, en effet.

    Cependant, le problème est du au fonctionnement même du malloc qu'à l'écriture du code.

    Comme je l'ai dit, chaque allocation dynamique de la mémoire est susceptible d'échouer. Si tu multiplies les malloc, tu multiplie ne nombre d'échecs possibles

    De plus, en effectuant un malloc par ligne, tu n'as aucune certitude que le dernier élément de la ligne N soit contigu au premier élément de la ligne N+1, et donc, tu risques très fort d'avoir un phénomène de "cache miss" beaucoup plus important que si tu avait alloué l'ensemble des éléments d'une seule traite.

    S'il n'y a aucune certitude que tu auras de meilleures performances en ayant tous les éléments contigus en mémoire, tu as, cependant, la certitude qu'elles seront, malgré tout, optimales. Certitude que tu ne peux pas avoir avec des éléments non contigus en mémoire

    Enfin, s'il est vrai que tout problème en informatique peut etre résolu par une indirection supplémentaire, chaque indirection vient avec un "niveau" de complexité au supplémentaire au niveau du code.

    Si l'on peut éviter une indirection qui n'est pas forcément indispensable, on s'évite forcément un certain niveau de complexité
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #13
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    En gros, cf ma signature:
    un pointeur en moins est une montagne d'erreurs en moins

  14. #14
    Membre expérimenté Avatar de moins1
    Homme Profil pro
    Autre
    Inscrit en
    Février 2013
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Autre
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 85
    Par défaut
    Je suis entièrement d'accord avec vous koala01 et leternel.

    C'est d'ailleurs ce que je fais dans mon exemple: j'alloue une grille de n rangées par n colonnes avec un seul malloc().

    Mais comme je trouve ça plus naturel d'utiliser les crochets chaque fois qu'on accède à une case, j'ai ajouter un pointeur de pointeur sur un t_case de taille n rangée. C'est mon second malloc(). Les valeurs de ce "tableau de pointeurs" sont assignées à ce qui correspond au début de chaque rangée dans la mémoire allouée lors du premier malloc(). Après tout calculer les adresses comporte aussi des risques d'erreurs et rend le code plus difficile à lire.

    J'ai donc, pour une grille deux malloc() et ce peut importe la taille de la grille. D'où mon deux malloc() c'est pas la fin du monde non plus.

    Mais bon c'est juste moi hein.


  15. #15
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par moins1 Voir le message
    Je suis entièrement d'accord avec vous koala01 et leternel.

    C'est d'ailleurs ce que je fais dans mon exemple: j'alloue une grille de n rangées par n colonnes avec un seul malloc().

    Mais comme je trouve ça plus naturel d'utiliser les crochets chaque fois qu'on accède à une case, j'ai ajouter un pointeur de pointeur sur un t_case de taille n rangée. C'est mon second malloc(). Les valeurs de ce "tableau de pointeurs" sont assignées à ce qui correspond au début de chaque rangée dans la mémoire allouée lors du premier malloc(). Après tout calculer les adresses comporte aussi des risques d'erreurs et rend le code plus difficile à lire.

    J'ai donc, pour une grille deux malloc() et ce peut importe la taille de la grille. D'où mon deux malloc() c'est pas la fin du monde non plus.

    Mais bon c'est juste moi hein.

    Oui, mais bon...

    1- Cela t'oblige à prendre l'adresse de ton tableau de case pour pouvoir y arriver (par habitude, j'ai horreur de prendre l'adresse d'un élément si je peux m'en passer, mais c'est une déformation issue du C++ )

    2- L'utilisation de crochet pose le problème de savoir si l'on travaille en [ligne][colonne] ou en [colonne][ligne].

    "Classiquement", les conventions nous inciteraient sans doute à travailler en [linge][colonne], mais il n'est pas exclu que, pour une raison ou une autre (cache miss éventuel du à certains accès plus récurrents que d'autres :question), on puisse décider de passer à un stockage sous la forme de [colonne][ligne].

    Le fait d'utiliser une fonction qui prend deux paramètres en entrée (ligne et colonne, justement ) permet de rajouter "juste ce qu'il faut" d'encapsulation afin de s'assurer que l'utilisateur n'aura qu'à suivre les conventions habituelles, indépendamment de la manière dont les données sont effectivement maintenues en mémoire

    Mais bon, ce n'est que mon point de vue de développeur plus habitué au C++ moderne qu'au C
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. problème fonctions callback
    Par youp_db dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 02/10/2005, 14h47
  2. probleme fonction gethostbyname
    Par oclone dans le forum Développement
    Réponses: 6
    Dernier message: 14/04/2005, 10h31
  3. probleme fonction syntaxe
    Par gIch dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 28/02/2005, 09h52
  4. Réponses: 10
    Dernier message: 19/05/2004, 11h41
  5. fonction qui initialise a blanc zone de texte
    Par access dans le forum Requêtes
    Réponses: 1
    Dernier message: 27/11/2003, 16h36

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