Je comprends mieux merci
Il me faudrait un exemple pour strcpy .. je comprend pas tant que j'ai pas d'exemple enfaite c'est trop complexe l'info ..
Je comprends mieux merci
Il me faudrait un exemple pour strcpy .. je comprend pas tant que j'ai pas d'exemple enfaite c'est trop complexe l'info ..
Je vais être direct : ouvre ton cours de CJ'ai jamais compris comment faire appel a mes fonctions ..
Comme te l'a justement expliqué Bysbobo, un free() sert à libérer de la mémoire qui a été réclamée (ou encore réservée) explicitement. Une telle réservation se fait avec malloc(), calloc() ou realloc(). Si tu n'as pas utilisé une de ces fonctions sur ta variable, tu ne dois pas appeler free() dessus.Comment ça ce fait qu'on a utiliser free sur nom et prenom et pas les autres champs ?
Ce n'est pas tant le risque de plantage qui est important. C'est surtout un problème de consommation mémoire inutile. Si tu fais une action toutes les minutes sans libérer la mémoire et que ton programme tourne pendant des mois, tu risques d'utiliser toute la mémoire de ton ordinateur (pour rien).En gros, toute allocation doit etre libérée par tes soins sinon sa peut planter.
Si tu veux copier une chaine dans une autre, oui. Exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part est-il nécessaire d'utiliser strcpy ?
Au passage, il doit y avoir des 10 aines d'exemple sur Google de l'utilisation de cette fonction. N'hésites pas aussi à regarder les ressources de Developpez, dans FAQ et Tutoriel. http://c.developpez.com/faq/?page=strings#STRINGS_init --> une entrée intéressante de la FAQ.
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 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char source[100] = "bonjour"; char dest[100] = {0}; printf("Avant [%s][%s]\n", source, dest); strcpy(dest, source); printf("Apres [%s][%s]", source, dest); return 0; }
Merci pour ta réponse je vais faire un tour !.
J'ai ensuite l'exercice 2.
Dans cette exercice je dois créer des listes chaînées dont les maillons contiennent des fiche_t. On utilisera alors les fonctions de l'exercice 1.
1. Définir la structure maillon_t qui contient un pointeur sur une fiche_t, nommé val, et un pointeur suiv vers un autre maillon_t.
2. Ecrire la fonction maillon_creer qui prend en entrée un pointeur sur une fiche et renvoit un pointeur sur un maillon_t. Pensez à initialiser le champs suiv.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 struct maillon_s{ fiche_t *val; maillon_t *suiv; }; typedef maillon_s maillon_t;
3. Ecrire la fonction maillon_detruire qui prend en entrée un pointeur sur un maillon_t, libère l'espace mémoire alloué dans la fonction maillon_creer et appel la fonction fiche_detruire (pas nécessairement dans cet ordre)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 maillon_t * maillon_creer(fiche_t *fiche) { maillon_t * res=(maillon_t*)malloc(sizeof(maillon_t)); res->val = fiche; res->suiv = NULL; return res; }
4. Ecrire la fonction récursive maillon_affiche_rec qui prend en entrée un pointeur sur un maillon_t, affiche son contenu à l'aide de la fonction fiche_affiche, puis affiche le maillon suivant. Attention au test d'arrêt.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 void maillon_detruire(maillon_t *m) { fiche_detruire(fiche_t *fiche); free(m->fiche); free(m); }
Alors la je vois pas comment faire j'essaye un petit truc..
5. Définir la structure liste_t qui contient un entier taille et un pointeur debut sur maillon_t.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 void maillon_affiche_rec (maillon_t *m) { printf("", m->val, m->fiche); m = m->suiv; maillon_affiche_rec(m); }
6. Ecrire la fonction liste_creer qui ne prend rien en entrée et renvoie un pointeur sur une liste_t de taille 0.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 struct liste_s{ int taille; maillon_t *debut; }; typedef liste_s liste_t;
7. Ecrire la fonction liste_ajouter_debut qui prend en entrée un pointeur sur une liste_t et un pointeur sur une fiche_t et ajoute la fiche au début de la liste (ne pas oublier de modifier la taille de la liste)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 void liste_creer() { liste_t *res = (liste_t*)malloc(sizeof(liste_t)); res -> debut = NULL; res -> taille = 0; return res; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 void liste_ajouter_debut(liste_t *l, fiche_t *f) { if (liste_creer(*l) == NULL) l-> debut = NULL; l-> taille = 0; else l->debut = f; l-> taille ++; }
3. Attention, si fiche_detruire() fait un free() (comme elle devrait le faire), ta fonction maillon_detruire() va faire un double-free dessus, très mauvais. Tu devrais supprimer cet appel à free().
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Bonjour,
2) Vérifier que l'allocation s'est bien déroulée serait mieux.
3) Qu'est censée faire cette ligne : fiche_detruire(fiche_t *fiche); ? Je ne peux qu'être d'accord avec Bktero.
Que se passe-t-il aussi si je rentre un pointeur NULL dans cette fonction ?
4) printf("", m->val, m->fiche); : Je ne vois aucun champ de ce nom dans ta structure.
Je te laisse déboguer cette partie pour te rendre compte de quelque chose... et justement te relire
6) Idem vérification de l'allocation.
7) Tu as créé une fonction void liste_creer(), et utilises liste_creer(*l). Il y a comme un problème...
Et je te conseille de revoir l'indentation de cette fonction. Le compilo saura te le rappeler
Donc ayant pris en compte vos reponses :
1. Définir la structure maillon_t qui contient un pointeur sur une fiche_t, nommé val, et un pointeur suiv vers un autre maillon_t.
2. Ecrire la fonction maillon_creer qui prend en entrée un pointeur sur une fiche et renvoit un pointeur sur un maillon_t. Pensez à initialiser le champs suiv.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 struct maillon_s{ fiche_t *val; maillon_t *suiv; }; typedef maillon_s maillon_t;
3. Ecrire la fonction maillon_detruire qui prend en entrée un pointeur sur un maillon_t, libère l'espace mémoire alloué dans la fonction maillon_creer et appel la fonction fiche_detruire (pas nécessairement dans cet ordre)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 maillon_t * maillon_creer(fiche_t *fiche) { maillon_t * res=(maillon_t*)malloc(sizeof(maillon_t)); if( res == NULL ) { printf("allocation impossible"); } res->val = val; res->suiv = NULL; return res; }
4. Ecrire la fonction récursive maillon_affiche_rec qui prend en entrée un pointeur sur un maillon_t, affiche son contenu à l'aide de la fonction fiche_affiche, puis affiche le maillon suivant. Attention au test d'arrêt.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 void maillon_detruire(maillon_t *m) { free(m); fiche_detruire(); }
5. Définir la structure liste_t qui contient un entier taille et un pointeur debut sur maillon_t.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 void maillon_affiche_rec (maillon_t *m) { printf("%d", m->val, m->suiv); m = m->suiv; maillon_affiche_rec(m); }
6. Ecrire la fonction liste_creer qui ne prend rien en entrée et renvoie un pointeur sur une liste_t de taille 0.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 struct liste_s{ int taille; maillon_t *debut; }; typedef liste_s liste_t;
7. Ecrire la fonction liste_ajouter_debut qui prend en entrée un pointeur sur une liste_t et un pointeur sur une fiche_t et ajoute la fiche au début de la liste (ne pas oublier de modifier la taille de la liste)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 void liste_creer() { liste_t *res = (liste_t*)malloc(sizeof(liste_t)); if( res == NULL ) { printf("allocation impossible"); } res -> debut = NULL; res -> taille = 0; return res; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 void liste_ajouter_debut(liste_t *l, fiche_t *f) { if (liste_creer == NULL) l-> debut = NULL; l-> taille = 0; else l->debut = f; l-> taille ++; }
2) et 6) Tes vérifications d'allocation sont à revoir...
Que se passe t-il si elle échoue ? Tu affiches ton message et puis ?
3) Quel est le rôle de la fonction fiche_detruire() ?
4) As-tu regardé la documentation de la fonction printf() ? man printf
Tu affiches le champ val avec %d, ok mais qu'en est-il du champ suiv ?
4) et 7) Mêmes deuxièmes remarques que précédemment.
2 et 6. Enfaite pour l'allocation on n'a jamais vu ce que vous me demander les profs acceptent la fonction sans la vérification.
Pour la fonction 3. On me demande de faire appel a la fonction fiche_detruire je ne sais pas donc j'ai tenter des choses stupides.
Fonction 4 le champ suiv pointe vers un maillon donc :
Code : Sélectionner tout - Visualiser dans une fenêtre à part printf("%d ,%p", m->val, m->suiv);
Si les profs acceptent de faire du code non sécurisé...
Il serait peut-être temps de réellement lire et comprendre un cours de C sur l'utilisation des fonctions et pointeurs histoire de faire des choses plus réfléchies ?
D'un autre côté, dans les cas d'école, une allocation mémoire n'échoue jamais. Donc on peut se permettre soit de ne pas gérer l'erreur, soit de la gérer avec un abort()...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je ne suis pas choqué qu'un programme scolaire (ou même un petit programme sans problème de robustesse) ne teste pas le retour des allocations dynamiques. Ne pas savoir qu'une allocation dynamique peut échouer est en revanche plus dommageable !
Y'a que moi chez qui cette réponse choque?
La fin de la question te dit de faire attention au test d'arrêt mais là tu tournes non stop non?
Si tu ne mets pas de
tu vas parcourir toute la mémoire possible sans t'arrêter...
Code : Sélectionner tout - Visualiser dans une fenêtre à part if( m->suiv !=NULL )
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager