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 :

Allocation dynamique d'un tableau de structure


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut Allocation dynamique d'un tableau de structure
    Bonjour,
    Je dois programmer un jeu de Yathzee pour un projet de fac en C, et j'ai un petit problème concernant une déclaration dynamique d'un tableau de structure. Je m'explique :
    J'ai deux structure (dans deux fichier .C différent)

    La première :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct FeuilleScore {  
    int partieSuperieure [9];  
    int partieInferieure [7];  
    int scoreFinal;  
    };
    (j'ai mis dans un fichier .h correspondant : struct feuilleScore

    et la deuxieme :
    (j'ai mis en début de fichier #include "ProjetB.h" (c'est le .h du fichier .c où j'ai déclaré ma structure feuilleScore))

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct Joueur {  
    char* nom;  
    int nblancerRestants;  
    int Des [5]; //les dés du joueur (5 dés)  
    struct FeuilleScore;  
    };
    Le but est de créer le bon nombre de structures Joueur (une pour chaque joueurs de la partie).

    j'ai donc fait cette petite fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     struct Joueur* nombreJoueurs(void){  
     int nombreJoueurs;  
     printf("Combien de joueurs vont participer a la partie ? (1/2/3/...)");  
     scanf("%d",&nombreJoueurs);  
        struct Joueur* tab;  
        tab = malloc(sizeof(tab) * nombreJoueurs);  
        return tab;  
    }
    jusque là pas de problèmes.
    Puis j'ai fais une fonction qui permet d'associer a chaque structures Joueurs le nom du joueur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void nomJoueurs (struct Joueur * tab) {  
        int i = 0;  
        for(i;i<sizeof(tab);i++){  
            printf("Nom du joueur %d ? ",i+1);  
            scanf("%s",tab[i].nom);  
        }  
    }
    sauf qu'a partir de là ... ça ne marche plus du tout, peut importe le nombre de joueurs , mon nomJoueurs me propose toujours le nom de deux joueurs a mètre, et ensuite windows me dit que mon programme a cessé de fonctionner.

    Je pense donc que le problème vient de mon allocation dynamique de ma structure. Dois-je faire la même chose pour la structure FeuilleScore qui est dans la structure Joueur ?

    Merci d'avance

  2. #2
    Invité
    Invité(e)
    Par défaut
    Il te faut un tableau à deux dimensions, le programme quitte car il fait une erreur de segmentation fault en essayant d'accéder à une zone qui ne lui a pas été allouée

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Salut

    donne la taille du pointeur et non la taille de l'objet pointé. Du coup, ça ne peut pas marcher correctement.

    Je trouve le nom de la fonction nombreJoueurs assez moyen, vu que sa principale fonction est d'allouer de la mémoire. creerJoueurs ou quelque chose du genre conviendrait peut-être mieux.

    Tu peux créer un tableau dynamique possédant un nombre d'éléments correspondant au nombre de joueurs, chacun de ces éléments étant un pointeur sur une structure Joueur. Et via une boucle, il suffit ensuite d'allouer de la mémoire pour chacun de ces pointeurs, d'une taille de la structure.

    La fonction retourne la mémoire allouée, mais elle doit aussi faire connaitre à la fonction appelante le nombre de joueurs saisi (on peut le faire en passant un pointeur sur "int" en argument, pointant sur un objet "int" de la fonction appelante, où il suffira de modifier la valeur pointée).

    Tu peux donc par exemple créer un prototype de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct Joueur ** creerJoueurs(int * nombre_joueurs)
    Et modifier aussi le prototype de la fonction nomJoueurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int nomJoueurs(struct Joueur ** joueurs , int nombre_joueurs)
    La fonction serait appelée comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct Joueur ** joueurs;
    int nombre_joueurs;
     
    joueurs = creerJoueurs(&nombre_joueurs);
    if (joueurs == NULL)
    {
     ... erreur ...
    } else
    {
    ...
    }
    ce qui permettrait ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ...
    if (nomJoueurs(joueurs , nombre_joueurs) == 0)
    {
     ... erreur ...
    } else
    {
    ...
    }
    ...

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    voila mes deux fonctions :

    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
    struct Joueur** creerJoueurs (int * nombre_joueurs){
        int i = 0;
    	int nombreJoueurs;
    	printf("Combien de joueurs vont participer a la partie ? (1/2/3/...) ");
    	scanf("%d",&nombreJoueurs);
    	*nombre_joueurs = nombreJoueurs;
        struct Joueur** tab;
        tab[nombreJoueurs];
        for(i;i<nombreJoueurs;i++){
            tab[i] =  malloc(sizeof(struct Joueur));
        }
        return tab;
    }
     
    void nomJoueurs (struct Joueur** tab,int nombre_joueurs) {
        int i = 0;
        printf("%d",nombre_joueurs);
        for(i;i<nombre_joueurs;i++){
            printf("Nom du joueur %d ? ",i+1);
            scanf("%s",(*tab[i]).nom);
        }
    }
    cependant , lorsque j'exécute mes fonction par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main (void) {
        int taille;
        nomJoueurs(creerJoueurs(&taille),taille);
    }
    je ne peu pas rentrer de nom pour les joueurs :/ qu'est-ce que j'ai loupé ?

  5. #5
    Invité
    Invité(e)
    Par défaut
    Tu dois malloquer ton tableau avant de l'utiliser !

    Cette ligne ne fait rien à part faire planter ton programme : tab[nombreJoueurs];

    Il y a de nombreux sujets sur le malloc de tableaux à deux dimensions, fais une petite recherche.

  6. #6
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct Joueur** creerJoueurs (int * nombre_joueurs)
    {
     ....
        struct Joueur** tab;
        tab[nombreJoueurs];
        for(i;i<nombreJoueurs;i++){
            tab[i] =  malloc(sizeof(struct Joueur));
        }
        return tab;
    }
    tab[nombreJoueurs] ne fait rien.
    tab[i] =.... est faux, puisqu'on n'a pas alloué de mémoire pour tab[i]

    Il faut également tester la réussite des allocations.
    Par exemple :
    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
    struct Joueur** creerJoueurs (int * nombre_joueurs)
    {
        int i ;
        int nombreJoueurs = 0;
        *nombre_joueurs  = 0;
         do
         {
              printf("Combien de joueurs vont participer a la partie ? (1/2/3/...)\n");
              scanf("%d",&nombreJoueurs);
         }while(nombreJoueurs <=0)
     
       // allocation de la table des pointeurs
        struct Joueur** tab = malloc(nombreJoueurs*sizeof *tab);
        if(tab != NULL)
        {
            // allocation des joueurs
            for(i=0;i<nombreJoueurs;i++)
            {
                 tab[i] =  malloc(sizeof(struct Joueur));
                 if(tab[i] == NULL) break;
            }
            if(i<nombreJoueurs) // erreur d'allocation dans tab[i]
            {
                     // récupérer la mémoire allouée pour les tab[k] k=0..i-1
                     // récupérer la mémoire allouée pour tab
                     // mettre tab à NULL
            }
        }
        if(tab != NULL)  *nombre_joueurs  = nombreJoueurs ;
        return tab;
    }
    Maintenant, pourquoi faire un tableau de pointeurs sur des structures joueurs plutôt qu'un tableau de structure joueurs ? Ce serait plus simple.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Citation Envoyé par TheChicken Voir le message
    voila mes deux fonctions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    struct Joueur** creerJoueurs (int * nombre_joueurs){
        int i = 0;
    	int nombreJoueurs;
    	printf("Combien de joueurs vont participer a la partie ? (1/2/3/...) ");
    	scanf("%d",&nombreJoueurs);
    	*nombre_joueurs = nombreJoueurs;
        struct Joueur** tab;
        tab[nombreJoueurs];
        for(i;i<nombreJoueurs;i++){
            tab[i] =  malloc(sizeof(struct Joueur));
        }
        return tab;
    }
    Quelques remarques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	int nombreJoueurs;
    	printf("Combien de joueurs vont participer a la partie ? (1/2/3/...) ");
    	scanf("%d",&nombreJoueurs);
    	*nombre_joueurs = nombreJoueurs;
    On peut écrire directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	printf("Combien de joueurs vont participer a la partie ? (1/2/3/...) ");
    	scanf("%d",nombre_joueurs);
    -------

    Ceci ne fait rien. En plus, ça déborde.
    Il faut allouer de la mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct Joueur** tab;
    tab = malloc( sizeof *tab * *nombre_joueurs);
    -------

    Il n'y a nulle part aucun contrôle sur le retour des malloc. C'est "dangereux" car si la fonction échoue ça fait planter le programme.

    -------

    Le programme doit toujours libérer lui-même la mémoire dynamique qu'il a allouée (une fois qu'il n'en a plus besoin)

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Maintenant, pourquoi faire un tableau de pointeurs sur des structures joueurs plutôt qu'un tableau de structure joueurs ? Ce serait plus simple.
    J'avoue que j'ai un peu compliqué l'affaire avec cette idée. C'était pas très utile pour ce genre de programme.
    Au pire, à ce stade (y a pas bcp de code encore), on peut revenir à l'autre solution, il y a peu de choses à modifier.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    J'ai complété le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if(i<nombreJoueurs){ // erreur d'allocation dans tab[i]
                for(k=0;k<nombreJoueurs;k++){
                    free(tab[k]);// récupérer la mémoire allouée pour les tab[k] k=0..i-1
                }
                free(tab);// récupérer la mémoire allouée pour tab
                tab = NULL;// mettre tab à NULL
            }
    mais ma fonction nomJoueurs ne fonctionne pas (je passe une fois dans ma boucle for (puisque "Nom du joueur 1 ? " apparait ), mais après mon programme bug)

    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
    void nomJoueurs (struct Joueur** tab,int nombre_joueurs) {
        int i = 0;
        char* temporaire;
        for(i;i<nombre_joueurs;i++){
            printf("Nom du joueur %d ? ",i+1);
            scanf("%s",temporaire);
            (*tab[i]).nom = malloc(sizeof(char)*strlen(temporaire)+1);
            strcpy(temporaire,(*tab[i]).nom );
        }
    }
    int main (void) {
        int taille;
        nomJoueurs(creerJoueurs(&taille),taille);
        return 0;
    }

  10. #10
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                for(k=0;k<i;k++){
                    free(tab[k]);// récupérer la mémoire allouée pour les tab[k] k=0..i-1
                }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        char temporaire[256]; // il faut un tableau, pas un pointeur    
        for(i=0;i<nombre_joueurs;i++){
            printf("Nom du joueur %d ? ",i+1);
            scanf("%s",temporaire);
            (*tab[i]).nom = malloc(sizeof(char)* strlen(temporaire)+1);// sizeof(char) est toujours 1
    // ou   tab[i]->nom = malloc(strlen(temporaire)+1); 
            strcpy(temporaire,(*tab[i]).nom ); 
            strcpy((*tab[i]).nom , temporaire);
    // ou   strcpy(tab[i]->nom , temporaire);
       }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nomJoueurs(creerJoueurs(&taille),taille);
    Pas astucieux puisque nomJoueurs() ne prévoit pas NULL comme premier argument, ce qui peut arriver en cas d'échec d'allocation
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    C'est presque finis ^^ mais il y a encore un bug, lorsque j'entre 2 utilisateurs, il me propose de mettre 3 nom (quand j'entre 9 il me propose 10 noms ect...) et ensuite windows me dis que mon programme a planté :/

    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
    struct Joueur {
    char* nom;
    int nblancerRestants;
    int Des [5]; //les dés du joueur (5 dés)
    struct FeuilleScore feuille_Score_Joueur;
    };
     
    struct Joueur** creerJoueurs (int * nombre_joueurs){
        int i ;
        int k;
        int nombreJoueurs = 0;
        *nombre_joueurs  = 0;
         do{
              printf("Combien de joueurs vont participer a la partie ? (1/2/3/...)\n");
              scanf("%d",&nombreJoueurs);
         }while(nombreJoueurs <=0);
       // allocation de la table des pointeurs
        struct Joueur** tab = malloc(nombreJoueurs*sizeof *tab);
        if(tab != NULL){
            // allocation des joueurs
            for(i=0;i<nombreJoueurs;i++){
                 tab[i] =  malloc(sizeof(struct Joueur));
                 if(tab[i] == NULL) break;
            }
            if(i<nombreJoueurs){ // erreur d'allocation dans tab[i]
                for(k=0;k<i;k++){
                    free(tab[k]);// récupérer la mémoire allouée pour les tab[k] k=0..i-1
                }
                free(tab);// récupérer la mémoire allouée pour tab
                tab = NULL;// mettre tab à NULL
            }
        }
        if(tab != NULL)  *nombre_joueurs  = nombreJoueurs ;
        return tab;
    }
     
    void nomJoueurs (struct Joueur** tab,int nombre_joueurs) {
        int i;
        char temporaire[256];
        for(i=0;i<nombre_joueurs;i++){
            printf("Nom du joueur %d ? ",i+1);
            scanf("%s",temporaire);
            (*tab[i]).nom = malloc(strlen(temporaire)+1);
            strcpy((*tab[i]).nom , temporaire);
        }
    }
     
    int main (void) {
        int taille;
        nomJoueurs(creerJoueurs(&taille),taille);
        return 0;
    }

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Citation Envoyé par TheChicken Voir le message
    C'est presque finis ^^ mais il y a encore un bug, lorsque j'entre 2 utilisateurs, il me propose de mettre 3 nom (quand j'entre 9 il me propose 10 noms ect...) et ensuite windows me dis que mon programme a planté :/
    Chez moi, ça tourne. Fais un coup de "rebuild" à ton projet.

    Par contre, comme l'a indiqué plus haut diogene, je t'ai proposé une solution inutilement compliquée. Je t'ai fait faire une allocation dynamique pour la création d'un tableau à 2 dimensions alors qu'un tableau à 1 dimension aurait largement suffi pour ce genre de programme.
    Comme apparemment il s'agit d'un exo pour l'école, ton prof risque de ne pas trop apprécier la solution que je t'ai proposée. Ca peut se comprendre à la rigueur.
    Je pense qu'il serait mieux (pour ta note) d'effectuer les quelques modifications pour revenir à une allocation pour un tableau à 1 dimension.

    (Je m'autoflagelle pour la peine... )

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par jeroman Voir le message
    Chez moi, ça tourne. Fais un coup de "rebuild" à ton projet.
    hum , c'est étrange parceque chez moi j'ai cette erreur là :
    " D:\_JB\Bureau\Nouveau dossier\Joueur.h|9|error: field 'feuille_Score_Joueur' has incomplete type| "

    et lorsque je clique sur le message d'erreur il me dit que c'est là (dans Joueur.h ligne 9) :
    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
    #ifndef _JOUEUR_H
    #define _JOUEUR_H
    #include "ScoreJoueur.h"
     
     
    typedef struct Joueur {
    char* nom ;
    int nblancerRestants;
    int Des [5]; //les dés du joueur (5 dés)
    struct FeuilleScore feuille_Score_Joueur;
    }
    joueur;
    //typedef struct Joueur joueur;
     
    struct Joueur** creerJoueurs (int * nombre_joueurs);
    void nomJoueurs (struct Joueur** tab,int nombre_joueurs);
    #endif
    alors j'ai p-e fait une bourde dans le .h de ScoreJoueur
    ScoreJoueur.h :
    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
    #ifndef _SCOREJOUEUR_H
    #define _SCOREJOUEUR_H
    #include "Joueur.h"
     
    typedef struct FeuilleScore {
    int partieSuperieure [8];
    int partieInferieure [6];
    int scoreFinal;
    }feuille_Score_Joueur;
    //typedef struct FeuilleScore feuille_Score_Joueur;
     
    void ajoutScore (struct Joueur joueur);
    void scorePartieSup(int position,struct Joueur joueur);
    void scorePartieInfint position,struct Joueur joueur);
    #endif

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Cette erreur est apparemment liée à l'ordre de chargement de tes fichiers header.
    Lorsque le compilateur arrive à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct FeuilleScore feuille_Score_Joueur;
    il ne connait pas encore struct FeuilleScore... car la structure est définie après.

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "Joueur.h"
     
    struct Joueur** creerJoueurs (int * nombre_joueurs){
        int i ;
        int k;
        int nombreJoueurs = 0;
        *nombre_joueurs  = 0;
         do{
              printf("Combien de joueurs vont participer a la partie ? (1/2/3/...)\n");
              scanf("%d",&nombreJoueurs);
         }while(nombreJoueurs <=0);
       // allocation de la table des pointeurs
        struct Joueur** tab = malloc(nombreJoueurs*sizeof *tab);
        if(tab != NULL){
            // allocation des joueurs
            for(i=0;i<nombreJoueurs;i++){
                 tab[i] =  malloc(sizeof(struct Joueur));
                 if(tab[i] == NULL) break;
            }
            if(i<nombreJoueurs){ // erreur d'allocation dans tab[i]
                for(k=0;k<i;k++){
                    free(tab[k]);// récupérer la mémoire allouée pour les tab[k] k=0..i-1
                }
                free(tab);// récupérer la mémoire allouée pour tab
                tab = NULL;// mettre tab à NULL
            }
        }
        if(tab != NULL)  *nombre_joueurs  = nombreJoueurs ;
        return tab;
    }
     
    void nomJoueurs (struct Joueur** tab,int nombre_joueurs) {
        int i;
        char temporaire[256];
        for(i=0;i<nombre_joueurs;i++){
            printf("Nom du joueur %d ? ",i+1);
            scanf("%s",temporaire);
            (*tab[i]).nom = malloc(strlen(temporaire)+1);
            strcpy((*tab[i]).nom , temporaire);
        }
    }
     
    int main (void) {
        int taille;
        nomJoueurs(creerJoueurs(&taille),taille);
        return 0;
    }
    le .h associé
    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
    #ifndef _JOUEUR_H
    #define _JOUEUR_H
     
     
     
    struct FeuilleScore {
    int partieSuperieure [8];
    int partieInferieure [6];
    int scoreFinal;
    }feuille_Score_Joueur;
     
    struct Joueur {
    char* nom ;
    int nblancerRestants;
    int Des [5]; //les dés du joueur (5 dés)
    struct FeuilleScore feuille_Score_Joueur;
    };
     
    struct Joueur** creerJoueurs (int * nombre_joueurs);
    void nomJoueurs (struct Joueur** tab,int nombre_joueurs);
    #endif
    lorsque je lance le programme, j'ai ça qui s'affiche :

    Combien de joueurs vont participer a la partie ? (1/2/3/...)
    3 (si je met 1 il me propose 3 noms et si je met 2 il me propose trois noms aussi )
    Nom du joueur 1 ? toto
    Nom du joueur 2 ? tutu
    Nom du joueur 3 ? tata
    Nom du joueur 4 ? tom

    il me propose toujours un joueur de plus ... la fonction rebuild est grisée chez moi, j'utilise CodeBlocks 10.05

  16. #16
    Invité
    Invité(e)
    Par défaut
    Je ne suis pas certain de ce que j'avance, mais il me semble que la façon dont tu initialises la variable Taille dans le main renvoie sur un comportement indéfini : en effet, selon l'ordre avec lequel il aborde la fonction nomjoueurs, Taille n'a pas la même valeur. Je te conseille donc de l'initialiser avant l'appel de fonction. Je ne suis pas sûr de la théorie, mais le problème est causé par cela.

    Au passage, s'il y a une erreur de malloc dans creerJoueurs, nomJoueurs segfaultera.

  17. #17
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    comment je fais pour l'initialiser autrement ? je ne peu pas utiliser de variables globales.

  18. #18
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    feydaykyn a raison :
    mais il me semble que la façon dont tu initialises la variable Taille dans le main renvoie sur un comportement indéfini
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        nomJoueurs(creerJoueurs(&taille),taille);
    L'ordre d'évaluation des arguments d'une fonction est indéfini.
    Si l'argument creerJoueurs(&taille) est évalué après l'argument taille, ce dernier n'est pas initialisé. Il faut procéder en deux temps :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        int taille;
        struct Joueur** tab = creerJoueurs(&taille);
        nomJoueurs(tab,taille);
    ce qui a l'avantage de récupérer l'adresse de la zone allouée par creerJoueurs() dont tu auras certainement besoin ensuite.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  19. #19
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Merci beaucoup ! a tous ! ça marche
    Je reviendrais sur ce post si jamais j'ai d'autres questions sur mon projet (je mettrais la balise [résolu] lorsque j'aurai finis).

  20. #20
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    J'ai une question.
    Lorsque je déclare un joueur, la structure FeuilleScore correspondant au joueur est aussi crée, mais comment sont initialisé les variables de FeuilleScore ?
    c'est a dire toutes les valeurs dans les tableau partieSuperieur et partieInferieur ainsi que scoreFinal ?

    edit :
    J'utilise cette condition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(joueur.feuille_Score_Joueur.partieSuperieure[position] != NULL){
        printf("Vous avez déjà validé cette combinaison");
        ajoutScore(joueur);
    }
    pour vérifier que le joueur n'a pas déjà validé la combinaison.
    Mon test ne marche pas parce que la valeur "par défaut" n'est pas null.

    aussi j'ai fais une fonction flush (puisque l'utilisation de fflush n'est pas conseillée )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void flush(void){
     
    int c = 0;
    while (c != '\n' && c != EOF) {
     
    c = getchar();
    }
    }
    j'ai juste a faire
    pour vider le tampon du flux standard ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 7
    Dernier message: 17/01/2012, 17h01
  2. Allocation dynamique d'un tableau de structures
    Par ryadh.naouar dans le forum C
    Réponses: 5
    Dernier message: 24/04/2008, 12h49
  3. Réponses: 67
    Dernier message: 13/02/2007, 18h08
  4. Réponses: 13
    Dernier message: 01/10/2006, 00h25
  5. [PRO*C] Allocation dynamique d'un tableau de VARCHAR
    Par NéalZheimer dans le forum Interfaces de programmation
    Réponses: 5
    Dernier message: 07/07/2006, 13h02

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