Les listes et les structures
Résolu/Fermé
safasahnoun
-
14 nov. 2012 à 13:20
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 - 14 nov. 2012 à 19:44
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 - 14 nov. 2012 à 19:44
A voir également:
- Les listes et les structures
- Dans la table des matières de ce document, le chapitre 6 et ses 2 sections n'apparaissent pas. trouvez l'erreur dans la structure du document et corrigez-la. mettez à jour la table des matières. quel est le mot formé par les lettres en majuscules de la table des matières après sa mise à jour ? - Forum Word
- Triez la liste comme sur cette illustration (attention, on ne voit que le début …). quel est le mot formé par les 6 dernières lettres de la colonne code ? - Forum Excel
- Le fichier contient une liste de prénoms. triez ce tableau par ordre alphabétique des prénoms. quel mot est formé par les 6 premières lettres de la colonne code ? - Forum Bureautique
- Ajoutez à la liste de contacts ana le goff, inscrite le 27 novembre 2015, dans la catégorie i. puis triez les contacts en les classant : par ordre alphabétique de leur nom de famille (critère principal), puis par date du plus récent au plus ancien (critère secondaire). quel mot apparaît à la verticale dans la colonne "catégorie" entre les lignes 200 et 209 (en-tête compris) ? ✓ - Forum Word
- Sql lister les tables ✓ - Forum Programmation
4 réponses
Char Snipeur
Messages postés
9688
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
2 octobre 2020
1 328
14 nov. 2012 à 15:41
14 nov. 2012 à 15:41
Salut.
déjà, je mettrais le typedef après la définition de la structure.
Je ne comprend pas l'intéret de la fonction new_dresseur, tu as fait du Java avant ?
d->nom = nom;
cette façon de faire est dangereuse, car tu lies un objet à une variable qui peut changer.
Je ne vois pas d'erreur, mais ta façon de coder est très tordu.
déjà, je mettrais le typedef après la définition de la structure.
Je ne comprend pas l'intéret de la fonction new_dresseur, tu as fait du Java avant ?
d->nom = nom;
cette façon de faire est dangereuse, car tu lies un objet à une variable qui peut changer.
Je ne vois pas d'erreur, mais ta façon de coder est très tordu.
[Dal]
Messages postés
6057
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mars 2023
1 043
Modifié par [Dal] le 14/11/2012 à 16:33
Modifié par [Dal] le 14/11/2012 à 16:33
Salut safasahnoun,
Sur la base de ton code posté dans ta question initiale, je pense que le problème vient du fait que tu alloues dans new_dresseur un espace mémoire pour la structure, mais qu'à l'intérieur de la structure tu n'alloues pas un espace pour stocker le "nom" (juste un espace pour le pointeur, et que tu te contentes d'écraser le pointeur de d->nom avec celui de nom, qui est le paramètre passé à ta fonction).
Je pense donc que tu pourrais faire quelque chose comme cela :
Dal
Sur la base de ton code posté dans ta question initiale, je pense que le problème vient du fait que tu alloues dans new_dresseur un espace mémoire pour la structure, mais qu'à l'intérieur de la structure tu n'alloues pas un espace pour stocker le "nom" (juste un espace pour le pointeur, et que tu te contentes d'écraser le pointeur de d->nom avec celui de nom, qui est le paramètre passé à ta fonction).
Je pense donc que tu pourrais faire quelque chose comme cela :
dresseur new_dresseur(char* nom)
{ /* creer nouveau dresseur */
dresseur *d;
d = malloc(sizeof(struct dresseur));
if (d == NULL )
{
printf("Erreur : impossible d'allouer nouveau dresseur\n");
exit(EXIT_FAILURE);
}
/* allouer l'espace nécessaire au stockage du nom */
d->nom = malloc(strlen(nom));
if (d->nom == NULL )
{
printf("Erreur : impossible d'allouer dresseur->nom\n");
exit(EXIT_FAILURE);
}
/* copier nom dans cet espace */
strcpy(d->nom, nom);
return *d;
}
Dal
[Dal]
Messages postés
6057
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mars 2023
1 043
14 nov. 2012 à 16:33
14 nov. 2012 à 16:33
Note que je n'ai pas regardé le reste de ton code dans https://forums.commentcamarche.net/forum/affich-26471633-les-listes-et-les-structures#6
Char Snipeur
Messages postés
9688
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
2 octobre 2020
1 328
Modifié par Char Snipeur le 14/11/2012 à 16:43
Modifié par Char Snipeur le 14/11/2012 à 16:43
C'est plus propre, mais ce n'est pas pour ça. Son code fonctionne bien chez moi.
Le problème de ton code, c'est que tu crée avec malloc un espace mémoire qui ne sera jamais libéré, car inaccessible.
Soit tu fais un vrai new et tu retournes un pointeur, soit tu fais un passage par valeur en retour grace à un objet temporaire.
Pointé sur un "const char*" comme safasahnoun fait ne pose pas de problème car cette chaine est constante, statique. Du coup, pas besoin de malloc pour réserver de l'espace mémoire. Cela dit, ce n'est pas une bonne façon de faire, mais elle ne pose pas de problème.
Le problème de ton code, c'est que tu crée avec malloc un espace mémoire qui ne sera jamais libéré, car inaccessible.
Soit tu fais un vrai new et tu retournes un pointeur, soit tu fais un passage par valeur en retour grace à un objet temporaire.
Pointé sur un "const char*" comme safasahnoun fait ne pose pas de problème car cette chaine est constante, statique. Du coup, pas besoin de malloc pour réserver de l'espace mémoire. Cela dit, ce n'est pas une bonne façon de faire, mais elle ne pose pas de problème.
[Dal]
Messages postés
6057
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mars 2023
1 043
Modifié par [Dal] le 14/11/2012 à 17:04
Modifié par [Dal] le 14/11/2012 à 17:04
S'il a le dresseur retourné par la fonction (d), il peut déterminer le pointeur vers le dresseur (&d), et il peut libérer dresseur->nom, et dresseur lui même. C'est peu orthodoxe, mais pourquoi pas.
Cela dit, comme tu le dis justement, s'il fait "dresseur d;" dans son main, il a déjà alloué cet espace, et le malloc d'allocation d'un nouveau dresseur est inutile dans la fonction, et ne fait qu'écraser le pointeur vers l'espace initial. Donc, de toutes façons, il y a un problème.
En revanche le 2ème malloc dans new_dresseur, lui, reste nécessaire me semble-t-il pour allouer l'espace nécessaire à la chaîne nom, car il n'est pas alloué du fait de la définition de la structure.
Il faudra, bien sûr, qu'il gère sa libération.
Dal
Cela dit, comme tu le dis justement, s'il fait "dresseur d;" dans son main, il a déjà alloué cet espace, et le malloc d'allocation d'un nouveau dresseur est inutile dans la fonction, et ne fait qu'écraser le pointeur vers l'espace initial. Donc, de toutes façons, il y a un problème.
En revanche le 2ème malloc dans new_dresseur, lui, reste nécessaire me semble-t-il pour allouer l'espace nécessaire à la chaîne nom, car il n'est pas alloué du fait de la définition de la structure.
Il faudra, bien sûr, qu'il gère sa libération.
Dal
Char Snipeur
Messages postés
9688
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
2 octobre 2020
1 328
14 nov. 2012 à 18:52
14 nov. 2012 à 18:52
et ne fait qu'écraser le pointeur vers l'espace initial. faux, le = copi les valeurs de l'un à l'autre, le pointeur est bien perdu.
le 2ème malloc dans new_dresseur, lui, reste nécessaire Non plus, car tu le fait pointé sur une chaine const char qui est garantie imuable. Il ne copie pas la chaine, il pointe dessus, donc pas de malloc nécessaire. Mais il ne faut pas faire comme ça.
le 2ème malloc dans new_dresseur, lui, reste nécessaire Non plus, car tu le fait pointé sur une chaine const char qui est garantie imuable. Il ne copie pas la chaine, il pointe dessus, donc pas de malloc nécessaire. Mais il ne faut pas faire comme ça.
[Dal]
Messages postés
6057
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mars 2023
1 043
14 nov. 2012 à 19:44
14 nov. 2012 à 19:44
Ok, je crois que je vois ce que tu veux dire. C'est vrai que c'est tordu :-)
Char Snipeur
Messages postés
9688
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
2 octobre 2020
1 328
14 nov. 2012 à 16:25
14 nov. 2012 à 16:25
C'est n'importe quoi ton truc. Les malloc ne servent à rie tes variable étant déclarées dés le début.
Pour copier les chaines de caractère on utilise strcpy(), pas =, sinon, gare aux erreurs inatendus. Tu écris ton programme comme dans un langage objet type Java ou C++, or c'est du C, il faut raisonner autrement. écrit plutôt :
new_pok(&pokemon1_1,"Dracaufeu", 650, pv1_1, attaques_1_1 );
écrit un code propre, ça évitera les erreurs.
Pour copier les chaines de caractère on utilise strcpy(), pas =, sinon, gare aux erreurs inatendus. Tu écris ton programme comme dans un langage objet type Java ou C++, or c'est du C, il faut raisonner autrement. écrit plutôt :
new_pok(&pokemon1_1,"Dracaufeu", 650, pv1_1, attaques_1_1 );
écrit un code propre, ça évitera les erreurs.
14 nov. 2012 à 16:02
14 nov. 2012 à 16:06
14 nov. 2012 à 16:11
14 nov. 2012 à 16:12
Modifié par safasahnoun le 14/11/2012 à 16:18
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
/*ATTAQUES:
1_structure de l'attaque :*/
typedef struct Attaque{
char* Nom;
int Force;
float Prob;
}Attaque;
//2_La création:
Attaque new_attack(char* Nom ,int Force ,float Prob){
Attaque* a;
a=malloc(sizeof(Attaque));
a->Nom = Nom;
a->Force = Force;
a->Prob = Prob ;
return (*a);
}
//3_Affichage
void get_attack(Attaque a){
printf("[%s,%d,%f]\n",a.Nom,a.Force,a.Prob);
}
//POKEMONS:
//1_structure :
typedef struct Pokemon {
char* Nom;
int HPMAX;
int HP;
Attaque Attaques[4];
}Pokemon;
//2_creation du pokemon
Pokemon new_pok(char* Nom, int HPMAX, int HP, Attaque Attaques[4]){
Pokemon *p;
p=malloc(sizeof(struct Pokemon));
p->Nom = Nom;
p->HPMAX= HPMAX;
p->HP = HP;
p->Attaques[0] = Attaques[0];
p->Attaques[1] = Attaques[1];
p->Attaques[2] = Attaques[2];
p->Attaques[3] = Attaques[3];
return *p ;
}
//POKEMON_LIST
//structure
typedef Pokemon p;
typedef struct maillon *Pokemon_list;
struct maillon {
p donnee;
Pokemon_list suivant;
};
Pokemon_list add(Pokemon_list liste, Pokemon p)
{Pokemon_list nouvelliste = malloc(sizeof(Pokemon_list));
nouvelliste->donnee = p;
nouvelliste->suivant = liste;
return nouvelliste;
}
//affichage
void get_pokemons_list(Pokemon_list a){
if (a== NULL) {printf ("liste vide");}
printf("[");
while (a->suivant != NULL)
{printf ("%s,",a->donnee.Nom);
a=a->suivant;}
printf("%s]",a->donnee.Nom);}
//DRESSEUR
//la structure dresseur
typedef struct dresseur dresseur;
struct dresseur { // defini la structure dresseur
char* nom;
Pokemon_list pokemon;
};
dresseur new_dresseur (char* nom, Pokemon_list Liste) { // creer nouveau dresseur
dresseur *d;
d=malloc(sizeof(struct dresseur));
d->nom = nom;
d->pokemon = Liste;
return *d;
}
void get_dresseur ( dresseur nom_dresseur ) {
printf ("Voici vos pokémons %s : ", nom_dresseur.nom);
}
int main(){
//création des attaques
//les attaque du pokemon 1 de dresseur 1
Attaque attaque_1_1_1 ,attaque_2_1_1 ,attaque_3_1_1 ,attaque_4_1_1 ;
//les attaque du pokemon 2 de dresseur 1
Attaque attaque_1_2_1 ,attaque_2_2_1 ,attaque_3_2_1 ,attaque_4_2_1 ;
//les attaque du pokemon 3 de dresseur 1
Attaque attaque_1_3_1 ,attaque_2_3_1 ,attaque_3_3_1 ,attaque_4_3_1 ;
//les attaque du pokemon 4 de dresseur 1
Attaque attaque_1_4_1 ,attaque_2_4_1 ,attaque_3_4_1 ,attaque_4_4_1 ;
//les attaque du pokemon 1 de dresseur 2
Attaque attaque_1_1_2 ,attaque_2_1_2 ,attaque_3_1_2 ,attaque_4_1_2 ;
//les attaque du pokemon 2 de dresseur 2
Attaque attaque_1_2_2 ,attaque_2_2_2 ,attaque_3_2_2 ,attaque_4_2_2 ;
//les attaque du pokemon 3 de dresseur 2
Attaque attaque_1_3_2 ,attaque_2_3_2 ,attaque_3_3_2 ,attaque_4_3_2 ;
//les attaque du pokemon 4 de dresseur 2
Attaque attaque_1_4_2 ,attaque_2_4_2 ,attaque_3_4_2 ,attaque_4_4_2 ;
//le dresseur 1
//pokemon 1
attaque_1_1_1 = new_attack ("Abime" , 55, 0.95);
attaque_2_1_1 = new_attack ("Balayage" , 105, 0.8);
attaque_3_1_1 = new_attack ("Cascade" , 150, 0.5);
attaque_4_1_1 = new_attack ("Eclair" , 40, 0.25);
// pokemon 2
attaque_1_2_1 = new_attack ("Poinglace" , 120, 0.7);
attaque_2_2_1 = new_attack ("Vol" , 50, 0.3);
attaque_3_2_1 = new_attack ("Souplesse" , 250, 0.1);
attaque_4_2_1 = new_attack ("Furie" , 15, 1.0);
// pokemon 3
attaque_1_3_1 = new_attack ("Plaquage" , 60, 0.25);
attaque_2_3_1 = new_attack ("Ligotage" , 90, 0.8);
attaque_3_3_1 = new_attack ("Mania", 65, 0.65);
attaque_4_3_1 = new_attack ("Damocles", 40, 0.15);
// pokemon 4 du dresseur
attaque_1_4_1 = new_attack ("Rugissement", 77, 0.65);
attaque_2_4_1 = new_attack ("Hurlement" , 150, 0.84);
attaque_3_4_1 = new_attack ("Ultrason" , 150, 0.5);
attaque_4_4_1 = new_attack ("Sonicboom" , 40, 0.45);
// Le dresseur 2
//pokemon 1
attaque_1_1_2 = new_attack ("Flammèche" , 78, 0.86);
attaque_2_1_2 = new_attack ("Hydrocanon" , 124, 0.28);
attaque_3_1_2 = new_attack ("Surf" , 89, 0.53);
attaque_4_1_2 = new_attack ("Ultralaser" , 28, 0.97);
// pokemon 2
attaque_1_2_2 = new_attack ("Picpic" , 86, 0.38);
attaque_2_2_2 = new_attack ("Sacrifice" , 42, 0.65);
attaque_3_2_2 = new_attack ("Riposte", 83, 0.5);
attaque_4_2_2 = new_attack ("Hypnose" , 17, 1);
// pokemon 3
attaque_1_3_2 = new_attack ("Reflet", 56, 0.95);
attaque_2_3_2 = new_attack ("Toxik" , 43, 0.8);
attaque_3_3_2 = new_attack ("Frustration" , 156, 0.4);
attaque_4_3_2 = new_attack ("Aurore" , 132, 0.25);
// pokemon 4
attaque_1_4_2 = new_attack ("Ouragan" , 115, 0.46);
attaque_2_4_2 = new_attack ("Teleport" , 69, 0.26);
attaque_3_4_2 = new_attack ("Avale" , 76, 0.55);
attaque_4_4_2 = new_attack ("Tranche" , 56, 0.97);
//declarations pour pokemons
//structures d'attaques
Attaque attaques_1_1[]= { attaque_1_1_1, attaque_2_1_1, attaque_3_1_1, attaque_4_1_1 };
Attaque attaques_2_1[]= { attaque_1_2_1, attaque_2_2_1, attaque_3_2_1, attaque_4_2_1 };
Attaque attaques_3_1[]= { attaque_1_3_1, attaque_2_3_1, attaque_3_3_1, attaque_4_3_1 };
Attaque attaques_4_1[]= { attaque_1_4_1, attaque_2_4_1, attaque_3_4_1, attaque_4_4_1 };
Attaque attaques_1_2[]= { attaque_1_1_2, attaque_2_1_2, attaque_3_1_2, attaque_4_1_2 };
Attaque attaques_2_2[]= { attaque_1_2_2, attaque_2_2_2, attaque_3_2_2, attaque_4_2_2 };
Attaque attaques_3_2[]= { attaque_1_3_2, attaque_2_3_2, attaque_3_3_2, attaque_4_3_2 };
Attaque attaques_4_2[]= { attaque_1_4_2, attaque_2_4_2, attaque_3_4_2, attaque_4_4_2 };
// les pokemons du dresseur 1
Pokemon pokemon1_1 ,pokemon1_2 ,pokemon1_3 ,pokemon1_4 ;
// les pokemons du dresseur 2
Pokemon pokemon2_1 ,pokemon2_2 ,pokemon2_3 ,pokemon2_4 ;
// creation des pokemons
int pv1_1=650,pv2_1=450, pv3_1=200, pv4_1=770, pv1_2=320, pv2_2=270,pv3_2=865,pv4_2=500;
pokemon1_1 = new_pok("Dracaufeu", 650, pv1_1, attaques_1_1 );
pokemon1_2 = new_pok("Raichu", 450, pv2_1, attaques_2_1 );
pokemon1_3 = new_pok("Taupiqueur", 200, pv3_1, attaques_3_1 );
pokemon1_4 = new_pok("Otaria", 770, pv4_1, attaques_4_1 );
pokemon2_1 = new_pok("Poissirène", 320, pv1_2, attaques_1_2 );
pokemon2_2 = new_pok("Floravol", 270, pv2_2, attaques_2_2 );
pokemon2_3 = new_pok("pikachu", 865, pv3_2, attaques_3_2 );
pokemon2_4 = new_pok("Bulbizarre", 500, pv4_2, attaques_4_2 );
//les dressurs:
Pokemon_list liste1=NULL;
liste1=add(liste1,pokemon1_1);
liste1=add(liste1,pokemon1_2);
get_pokemons_list(liste1);
dresseur d;
d=new_dresseur("s",liste1);
get_dresseur(d);
return 0;
}