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 :

Tableau dans typedef


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut Tableau dans typedef
    Bonjour,
    J'ai le typedef suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct{
    int nbcoups;
    coup coups[];
    }parties;
    avec coup :
    Dans une fonction, j'ai besoin de retourner un objet de type partie, je dois donc affecter des valeurs à nbcoups et à coups[].
    Pas de problème pour nbcoups, cependant je n'arrive pas à remplir le tableau coups[].
    Quelqu'un aurait une solution pour ça ?

    Merci d'avance.

  2. #2
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Salut,

    ton tableau coup dans la struct parties est un tableau flexible (type tableau incomplet en dernier membre d'une structure), cela requiert des allocations un peu différentes. Peux-tu nous montrer un peu ton code ?
    Pourquoi n'utilises-tu pas un pointeur sur coup à la place ?

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    J'ai essayé ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    partie p;
    p.nb = 5;
     
    p.coups = malloc(sizeof(coup)*p.nb)
    et j'ai une erreur à l'execution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    invalide use of flexible array member

  4. #4
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Je pense que le plus simple pour toi est de définir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct{
    int nbcoups;
    coup* coups;
    }parties;
    Ce sera plus simple si tu veux faire des mallocs sur coups.

  5. #5
    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
    Tu as le choix :

    1- En utilisant un pointeur pour le champ coups comme indiqué par kwariz. Dans ce cas, le tableau n'est pas inclus dans la structure, seule son adresse l'est.

    2- En utilisant un "flexible array", comme dans ta définition initiale. Dans ce cas, le tableau est inclus dans la structure et il faut en tenir compte à la création d'un objet de ce type. 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
    #include <stdlib.h>
    typedef char coup[3];
    typedef struct
    {
       int nbcoups;
       coup coups[];
    }parties;
    /*------------------------------*/
    int main(void)
    {
     int n = 3;
     parties * p = malloc(sizeof(parties)+ sizeof(coup)*n);
     p->nbcoups = n;
     p->coups[2][2] = 22;
     p->coups[1][1] = 11;
     p->coups[0][1] = 10;
     free(p);
     return 0;
    }

  6. #6
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Donc si tu n'as pas le choix ...
    Tu ne demandes pas la bonne chose à ton printf (il ne faut pas non plus oublier le ; à la fin de la ligne ...)

    %c -> affiche un caractère, le caractère 22 est un caractère non imprimable -> tu ne vois rien

    %d -> c'est ce que tu veux car il affiche une valeur entière

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Bonjour,
    Désolé j'ai supprimé mon précédent message (fausse manip ...)
    Je disais donc que je n'avais pas le choix des types.

    Aussi j'ai essayé ce que tu as marqué diogene et ça marche bien dans ton exemple mais pas dans ma fonction.
    Ma fonction :
    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
    partie coups_possible(othellier p, joueur j){ /* qui renvoie la liste des coups possibles du joueur j sur l’othellier p*/
    	char a,b;
    	coup c;
    	int i,n=0;
    	//coup* tab = malloc(sizeof(coup)*z.nbcoups);
    	for(a = '0'; a < '8'; a++){
    		for(b = 'A'; b < 'I'; b++){
    			c[0]=j;
    			c[1]=b;
    			c[2]=a;
    			if(est_possible(p,c)){
    				n++;				
    			}
    		}
    	}
     
    	partie * z = malloc(sizeof(partie)+ sizeof(coup)*n);
    	z-> nbcoups = n;
     
     
    	for(a = '0'; a < '8'; a++){
    		for(b = 'A'; b < 'I'; b++){
    			c[0]=j;
    			c[1]=b;
    			c[2]=a;
    			if(est_possible(p,c)){
    				for(i = 0; i < n; i++){
    				 	z->coups[i][2] = a;
    				 	z->coups[i][1] = b;
    				 	z->coups[i][0] = j;
    				}
    			}
    		}
    	}
    	printf("nbr coups = %d\n", z-> nbcoups);
    	return *z;
    }

    Puis dans une fonction main, je veux vérifier le contenu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main(void){
     
    	othellier* b = create_othellier();
    	affiche_othellier(*b);
    	int i;
    	partie a;
    	a = coups_possible(*b,'N');
    		printf("Les coups possibles sont %d\n",a.coups[1][0]); //juste pour tester si il y a qqchose dans le tableau
     
    	return 0;
    }
    Ca me retourne : 0 (car j'ai mis un %d comme tu me l'as indiquer kwariz, avant cela n'affichait juste rien ^^ )

  8. #8
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Soit tu mets des les caractères '0' '1' ... et tu les affiches avec %c
    Soit tu mets les valeurs 0 1 ... et tu les affiches avec %d

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Avec %c ça n'affiche rien non plus. L'erreur ne vient pas du printf je pense mais du tableau en lui même.

  10. #10
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Exécute ton code en mode pas à pas pour voir si tu rentres dans la partie if (est_possible(p,c)) ... si tu ne le remplis pas tu n'auras rien dedans.
    Mais si tu le remplis avec des caractères utilises %c.

    C'est un projet d'école ?

  11. #11
    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
    On ne peut pas créer une partie de cette façon qui ne prend pas en compte la taille du tableau "flexible". En fait, la structure est créée dynamiquement par coups_possible() et connue uniquement par son adresse.
    On devrait avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    partie * coups_possible(othellier p, joueur j){
    .....
    	partie * z = malloc(sizeof(partie)+ sizeof(coup)*n);
    	z-> nbcoups = n;
    .....
     return z;
    }
    .....
       partie * a = coups_possible(*b,'N');
       printf("Les coups possibles sont %d\n",a->coups[1][0]); //juste pour tester si il y a qqchose dans le tableau
    .....
       free(a);

  12. #12
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 482
    Points : 13 680
    Points
    13 680
    Billets dans le blog
    1
    Par défaut
    Voici un lien que j'avais beaucoup apprécié quand j'avais voulu comprendre les flexible array members

    https://www.securecoding.cert.org/co...are+to+be+used

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Bonjour,
    Merci pour vos réponses.

    J'ai essayé d'initialiser le tableau avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    partie* a = coups_possible(*b,'N');
    mais ça me retourne une erreur à la compilation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ gcc debut\(2\).c -o debut\(2\)
    debut(2).c: In function ‘main’:
    debut(2).c:490: error: incompatible types when initializing type ‘struct partie *’ using type ‘partie’
    @kwaritz : par des tests antérieurs je m'étais rendu compte que j'entrais bel et bien dans le if. En enffet, nbcoups était bel et bien égal à 4;

    Et oui ce projet m'a été donné à faire par ma fac, le but final étant de faire un othello et de pouvoir jouer contre l'ordi avec plusieurs niveaux de difficulté.


    EDIT :
    J'ai essayé de faire une fonction pour re vérifier le if, une fonction qui affecte une valeur à nbcoups.

    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
    int Ncoups_possible(othellier p, joueur j){ /* qui renvoie la liste des coups possibles du joueur j sur l’othellier p*/
      char a,b;
      coup c;
      int i,n=0;
      //coup* tab = malloc(sizeof(coup)*z.nbcoups);
      for(a = '0'; a < '8'; a++){
        for(b = 'A'; b < 'I'; b++){
          c[0]=j;
          c[1]=b;
          c[2]=a;
          if(est_possible(p,c)){
    	n++;				
          }
        }
      }
      partie * z = malloc(sizeof(partie)+ sizeof(coup)*n);
      z-> nbcoups = n;
     
      return n;
    }
    Ca me retourne une segmentation fault à l'exécution ...

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Et surtout une fuite de mémoire.

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Comment ça ?

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Tu "oublies" z sans faire de free() dessus.

  17. #17
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    J'ai beau retouner le programme dans tout les sens j'ai toujours une segmentation fault :

    Les types :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef char coup [3];
    typedef struct { 
    	int nbcoups;
    	coup coups[];
    } partie;
    La fonction qui me pose problème suivi de la main pour tester :
    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
     
    partie * coups_possible(othellier p, joueur j){ 
    	char a,b;
    	coup c;
    	int i,n=0;
     
    	for(a = '0'; a < '8'; a++){
    		for(b = 'A'; b < 'I'; b++){
    			c[0]=j;
    			c[1]=b;                            //initialisation de nbcoups
    			c[2]=a;
    			if(est_possible(p,c)){
    				n++;				
    			}
    		}
    	}
     
    	partie * z = malloc(sizeof(partie)+ sizeof(coup)*n);
    	z-> nbcoups = n;
     
     
    	for(a = '0'; a < '8'; a++){
    		for(b = 'A'; b < 'I'; b++){
    			c[0]=j;
    			c[1]=b;
    			c[2]=a;
    			if(est_possible(p,c)){
    				for(i = 0; i < n; i++){
    				 	z->coups[i][2] = a;
    				 	z->coups[i][1] = b;
    				 	z->coups[i][0] = j;
    				}
    			}
    		}
    	}
    	printf("nbr coups = %d\n", z-> nbcoups);
    	return z;
    }
     
     
    int main(void){
     
    	othellier* b = create_othellier();
    	affiche_othellier(*b);
    	int i;
    	partie * a = coups_possible(*b,'N');
    	printf("Les coups possibles sont %d\n",a->coups[0][0]); //juste pour tester si il y a qqchose dans le tableau
    	free(a);
    	return 0;
    }
    Qu'est-ce qui peut bien causé cette erreur de segmentation ?

    Merci d'avance.

  18. #18
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 482
    Points : 13 680
    Points
    13 680
    Billets dans le blog
    1
    Par défaut
    Si tu ne sais pas ce qui cause une erreur de segmentation, tu as 3 solutions :
    1. lire et relire ton code, mais tu ne trouveras pas toujours ton erreur
    2. mettres des printf() partout pour savoir où le plantage à lieu, mais c'est un peu fastidieux et tu ne sais pas forcément avec précision où ça plante
    3. utiliser un débugueur, c'est la solution la plus efficace. Bien que la moins simple pour un débutant, il est essentiel de passer par là

    Tu peux mixer les techniques pour cibler l'endroit, c'est que tu feras au final

  19. #19
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Difficile de répondre sans le code de est_possible().

Discussions similaires

  1. Tableau dans une interface idl
    Par Polochon2001 dans le forum CORBA
    Réponses: 2
    Dernier message: 14/05/2004, 09h44
  2. [langage] Tableau dans hashage
    Par iago dans le forum Langage
    Réponses: 2
    Dernier message: 26/01/2004, 16h19
  3. Réponses: 6
    Dernier message: 26/01/2003, 13h45
  4. [VB6]Passage d'un tableau dans une DLL écrite en delphi
    Par flash dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 20/09/2002, 10h15
  5. Réponses: 2
    Dernier message: 27/05/2002, 19h46

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