Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1378 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  demande de validation d'une fonction en c avec des pointeurs

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

demande de validation d'une fonction en c avec des pointeurs

n°232682
ddpforman
Posté le 22-10-2002 à 22:06:54  profilanswer
 

j'ai la structure suivante :
 
typedef struct commande {
 int pid;
 char **nom;
 struct commande *suivant;
} COMMANDES;
 
 
Que pensez vous de cette fonction pour libérer tous les espaces mémoires qui auraient pu etre pris:
 
 
void efface( COMMANDES *com){
  int n;  
  //printf("Début Efface tout pointeur\n" );
   
  if (com) {
     
    if (com->suivant) {
      efface(com->suivant);
    }
     
    if (com->nom) {  
      for(n=0;com->nom[n];n++) free(com->nom[n]);
    }
     
    free (com->nom);
  }
   
  free(com);
   
  //printf("Fin Efface tout pointeur\n" );
}
 
 
 
est elle exacte?compléte?

mood
Publicité
Posté le 22-10-2002 à 22:06:54  profilanswer
 

n°232684
Taz@PPC
saloperie de i=`expr $i + 1`;
Posté le 22-10-2002 à 22:11:18  profilanswer
 

je capte rien a ton truc...
 
c'est tou simplement une liste en plus compliqué...


---------------
du bon usage de rand [C] / [C++]
n°232688
ddpforman
Posté le 22-10-2002 à 22:23:11  profilanswer
 

ben oui en plus compliqué

n°232690
Taz@PPC
saloperie de i=`expr $i + 1`;
Posté le 22-10-2002 à 22:24:15  profilanswer
 

ddpforman a écrit a écrit :

ben oui en plus compliqué




 
 :non:  
 
en plus chiatique et inutile
 
je vois pas l'utilité de ton truc...


---------------
du bon usage de rand [C] / [C++]
n°232696
ddpforman
Posté le 22-10-2002 à 22:29:14  profilanswer
 

ben il faut supprimer les mallocs de chaque élément de la structure.. vous etes d'accord?  comme une liste chainée...  
 
mais il faut aussi supprimer ceux de nom qui est un char **
non?

n°232702
ddpforman
Posté le 22-10-2002 à 22:36:49  profilanswer
 

personne ne me confirme alors?

n°232706
sombresong​e
Posté le 22-10-2002 à 22:50:08  profilanswer
 

Axiome numero 1 de l'etudiant: Pourquoi faire simple quand on peut faire compliquer
 :D

n°232711
ddpforman
Posté le 22-10-2002 à 23:01:44  profilanswer
 

ben non, je sais bien qu'on peut laisser sans libérer  
ou bien en libérant que les éléments de la structure
mais notre prof nous a dit que à tout malloc doit correspondre un free
sinon, c pas propre..  
 
alors il y aurait pas qq experts pour m'aider please?

n°232713
lorill
Posté le 22-10-2002 à 23:04:56  profilanswer
 

ddpforman a écrit a écrit :

 
alors il y aurait pas qq experts pour m'aider please?




 
 :hello:  
 
ben je croyais que t'étais une super bête, moi ? je suis déçu, la...

n°232892
ddpforman
Posté le 23-10-2002 à 13:06:58  profilanswer
 

up

mood
Publicité
Posté le 23-10-2002 à 13:06:58  profilanswer
 

n°232977
TotOOntHeM​ooN
Posté le 23-10-2002 à 14:58:22  profilanswer
 

Ca ma l'air pas trop mal.
Il y a une condition quand même :
Il faut commancer par effacer le dernier élément de la liste puis revenir au précédent, etc... jusqu'au premier... Sinon, tu te coupe l'herbe sous le pied ! (mais tu y avais forcément pensé !)

n°232987
nykouze
Posté le 23-10-2002 à 15:06:00  profilanswer
 

TotOOntHeMooN a écrit a écrit :

Ca ma l'air pas trop mal.
Il y a une condition quand même :
Il faut commancer par effacer le dernier élément de la liste puis revenir au précédent, etc... jusqu'au premier... Sinon, tu te coupe l'herbe sous le pied ! (mais tu y avais forcément pensé !)




 
c ce qu'il fait, avec son appel a efface en recursif. Mais personnellement, dérécursifie ta fonction, ca sera d'autant plus propre.
 
Edit: p-e une petite erreur avec ton free(com) qui est a l'exterieur du if(com) et qui risque de segv si com == Null. Enfin, j'ai un peu de mal a voir le parenthesage, ton coding style est moche :D


Message édité par nykouze le 23-10-2002 à 15:08:15
n°233012
TotOOntHeM​ooN
Posté le 23-10-2002 à 15:16:24  profilanswer
 

Effectivement...
 
Tien, tu ne voudrais pas réponde à ma question de conversion dec<->hexa sur le forum ?

n°233052
ddpforman
Posté le 23-10-2002 à 15:50:26  profilanswer
 

en effet, si le com est déjà null: pas besoin de faire un free(com)
merci beaucoup...  
c toujours agréable de recevoir une aide :-)  
 
à bientot sans doute :-)

n°233055
TotOOntHeM​ooN
Posté le 23-10-2002 à 15:53:19  profilanswer
 

ddpforman a écrit a écrit :

en effet, si le com est déjà null: pas besoin de faire un free(com)
merci beaucoup...  
c toujours agréable de recevoir une aide :-)  
 
à bientot sans doute :-)  




 
Oui, par contre il faut bien le faire a la fin du if comme l'a dit nykouze !
 
if (com)
{
  ...
  free (com);
}

n°233063
Taz@PPC
saloperie de i=`expr $i + 1`;
Posté le 23-10-2002 à 16:00:32  profilanswer
 

je vois toujours pas a quois ert ton truc a moins que tu réinventes l'eau chaude.
 
tu peux donner un exemple d'utilisation (et aps qu'une seule linge, je veux un main de test)


---------------
du bon usage de rand [C] / [C++]
n°233323
ddpforman
Posté le 23-10-2002 à 22:00:45  profilanswer
 

c pas le pb...  
y'a pas d'exemple d'utilisation
si tu as ça, tu dois executer la fonction
si tu veux, la fonction c'est juste pour faire propre...
tu peux mettre cette fonction dans le main.
 
le probléme c'est pour libérer des espaces que tu as alloué
pour un char * mot
pour pouvoir remplir le mot, tu dois faire un malloc.
dés que tu as fini, tu dois faire un free(mot) pour redonner au systeme l'espére que tu avais réservé.
pour un char** texte, tu dois faire la meme chose
mais tu dois libérer l'espace pour chaque mot du texte
et ensuite libérer l'espace réservé pour le texte..  
c bizarre mais c'est comme ça
et comme tout ça est dans structure (la liste chainé en plus compliqué :-) )  
eh bien tu dois libérer chaque élément de la structure aprés avoir libérer l'intérieur.

n°233538
Musaran
Cerveaulté
Posté le 24-10-2002 à 03:39:56  profilanswer
 

Les deux free seraient mieux avant les accolades fermantes.
"free(NULL)" marche quand même, mais pourquoi tenter le diable et perdre en performance ?  
 
Perso, je préfères comme ça:

Code :
  1. void efface( COMMANDES *com){
  2. for( ; com!=NULL ; com= com->suivant ){
  3.  if (com->nom != NULL){
  4.   char** p;
  5.   for(p= com->nom ; *p!=NULL ; ++p)
  6.    free(*p);
  7.   free (com->nom);
  8.  }
  9.  free(com);
  10. }
  11. }


Mais pourquoi je réponds à un gars qui n'utilises pas [cpp] moi ?


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°233770
ddpforman
Posté le 24-10-2002 à 13:56:23  profilanswer
 

Code :
  1. ah excuse moi, je ne connaissais pas cpp !!!
  2. je l'utiliserais maintenant
  3. (j'ai mis du temps à comprendre ce que c'était :-)
  4. c'est juste un test: biensur je l'utiliserais pour le code :-)


 

n°233775
max2048
Begin The Begin
Posté le 24-10-2002 à 14:01:11  profilanswer
 

Musaran a écrit a écrit :

Les deux free seraient mieux avant les accolades fermantes.
"free(NULL)" marche quand même, mais pourquoi tenter le diable et perdre en performance ?  
 
Perso, je préfères comme ça:

Code :
  1. void efface( COMMANDES *com){
  2. for( ; com!=NULL ; com= com->suivant ){
  3.  if (com->nom != NULL){
  4.   char** p;
  5.   for(p= com->nom ; *p!=NULL ; ++p)
  6.    free(*p);
  7.   free (com->nom);
  8.  }
  9.  free(com);
  10. }
  11. }


Mais pourquoi je réponds à un gars qui n'utilises pas [ cpp] moi ?




 
Je propose :  
 

Code :
  1. void libererMemoire(COMMANDES *c) {
  2.     int i;
  3.     COMMANDES *tmp=c;
  4. while (tmp) {
  5.     c = c->suivant;
  6.  i = 0;
  7.  for (i=0; tmp->nom[i]; i++)
  8.   free(tmp->nom[i]);
  9.  free(tmp->nom);
  10.  free(tmp);
  11.  tmp = c;
  12. }
  13. }


Message édité par max2048 le 24-10-2002 à 14:02:46
n°233777
ddpforman
Posté le 24-10-2002 à 14:01:37  profilanswer
 

ah oui merci beaucoup,  
celle solution fait programmation extreme :-)  
 
y'a plus qu'as la faire valider par mon binome :-)  
pour l'inserer dans le programme
 
merci

n°233778
ddpforman
Posté le 24-10-2002 à 14:04:20  profilanswer
 

moi, je préfére celle de Musaran

n°233779
max2048
Begin The Begin
Posté le 24-10-2002 à 14:06:21  profilanswer
 

ddpforman a écrit a écrit :

moi, je préfére celle de Musaran




 
La mienne elle fonctionne, au moins :o

n°233896
BifaceMcLe​OD
The HighGlandeur
Posté le 24-10-2002 à 15:23:55  profilanswer
 

Moi je préfère les conditions qui ne contiennent que des expressions booléennes (au moins du point de vue logique). Et un pointeur n'est pas un booléen (par contre, le comparer à NULL rend un booléen).
Et les boucles qui n'utilisent "for" que quand le nombre d'itérations est connu à l'avance.
 
max2048> Ton "i=0" tout seul ne sert à rien puisque la première instruction de la boucle qui suit initialise i à 0.
 

Code :
  1. void efface(COMMANDES* com) {
  2.   // Modifier les paramètres en entrée, c'est pas bien.
  3.   COMMANDES*  pcommande = com;
  4.   while (pcommande != NULL) {
  5.     if (pcommande->nom != NULL) {
  6.       // Ca aurait été plus propre de stocker la longueur du
  7.       // tableau, plutôt que d'utiliser une entrée du tableau
  8.       // à NULL pour en signaler la fin.
  9.       char**  ppnom = pcommande->nom;
  10.       while (*ppnom != NULL) {
  11.         free(*ppnom);
  12.         *ppnom = NULL;
  13.         ppnom++;
  14.       }
  15.       free(pcommande->nom);
  16.       pcommande->nom = NULL;
  17.       pcommande->nom = NULL;
  18.       pcommande = pcommande->suivant;
  19.     }
  20.     free(pcommande);
  21.     pcommande = NULL;
  22.   }
  23. }

 

n°234100
Kortyburns
Posté le 24-10-2002 à 20:36:50  profilanswer
 

Musaran a écrit a écrit :

Les deux free seraient mieux avant les accolades fermantes.
"free(NULL)" marche quand même, mais pourquoi tenter le diable et perdre en performance ?  
 
Perso, je préfères comme ça:

Code :
  1. void efface( COMMANDES *com){
  2. for( ; com!=NULL ; com= com->suivant ){
  3.  if (com->nom != NULL){
  4.   char** p;
  5.   for(p= com->nom ; *p!=NULL ; ++p)
  6.    free(*p);
  7.   free (com->nom);
  8.  }
  9.  free(com);
  10. }
  11. }


Mais pourquoi je réponds à un gars qui n'utilises pas [cpp] moi ?




 
Elle est pas mal cette fonction, mais vous oubliez un detail : dans une liste chainée, il peut arriver qu'un maillon soit pointé par deux pointeurs : ça veut dire que la fonction ci-dessus va planter lorsque free() voudra liberer le maillon deja libéré.  
:hello:


---------------
Learn to live or live to learn ? Studies or not studies ?
n°234255
Musaran
Cerveaulté
Posté le 25-10-2002 à 05:03:11  profilanswer
 

max2048 a écrit a écrit :

La mienne elle fonctionne, au moins :o



Non plus. Elle indice un pointeur qui peut être NULL: "tmp->nom[ i]".
 
J'avais pas testé. C'est pas bien, mais tester c'est long...
Tu aurais pu signaler le problème: Accès après libération... j'ai honte !
Version illisible:

Code :
  1. #define FollowAndFree(p,mem,tmp) ((tmp)= (p)->mem,free(p),(void)((p)= (tmp)))
  2. void efface(COMMANDES* pcom){
  3. for(COMMANDES* ptemp ; pcom!=NULL ; FollowAndFree(pcom,suivant,ptemp)){
  4.  if (pcom->nom != NULL){
  5.   for(char** p= pcom->nom ; *p!=NULL ; ++p)
  6.    free(*p);
  7.   free (pcom->nom);
  8.  }
  9. }
  10. }


Version normale:

Code :
  1. void efface(COMMANDES* pcom){
  2. COMMANDES* ptemp;
  3. while(pcom!=NULL){
  4.  if (pcom->nom != NULL){
  5.   for(char** p= pcom->nom ; *p!=NULL ; ++p)
  6.    free(*p);
  7.   free (pcom->nom);
  8.  }
  9.  ptemp= pcom->suivant; //lire le suivant...
  10.  free(pcom); //avant de libérer
  11.  pcom = ptemp;
  12. }
  13. }


 

BifaceMcLeOD a écrit :

 
Moi je préfère les conditions qui ne contiennent que des expressions booléennes (au moins du point de vue logique). Et un pointeur n'est pas un booléen (par contre, le comparer à NULL rend un booléen).



Pareil.
 

Citation :

Et les boucles qui n'utilisent "for" que quand le nombre d'itérations est connu à l'avance.

Là, par contre... J'ai beau chercher, je ne vois pas pourquoi.
J'utilise for dès que j'ai au moins 2 des 3 termes [init, test, next].
 
Mettre à NULL un pointeur libéré reste discutable.
En effet, NULL est un argument valide pour certaines fonctions.
On peut vouloir faire comme certains débogueurs, mettre une valeur bogus magique comme ça:

Code :
  1. #define FREENULL(p) (free(p), (void)((p)= NULL))
  2. #define FREEFOIL(p) (free(p), (void)((p)= (void*)0xCCCCCCCC))

En C++, ça ne passe pas... NULL non plus n'est pas garanti.
 
Tu as raté la fin de ta fonction, comme moi...

Code :
  1. void efface(COMMANDES* com) {
  2. COMMANDES*  pcommande= com, *ptemp;
  3. while (pcommande != NULL) {
  4.  if (pcommande->nom != NULL) {
  5.   char**  ppnom = pcommande->nom;
  6.   while (*ppnom != NULL) {
  7.    free(*ppnom);
  8.    *ppnom = NULL;
  9.    ppnom++;
  10.   }
  11.   free(pcommande->nom);
  12.   pcommande->nom = NULL;
  13.  }
  14.  ptemp= pcommande->suivant; //lire le suivant...
  15.  free(pcommande);//...avant de libérer !
  16.  pcommande = ptemp;
  17. }
  18. }

 
 

Kortyburns a écrit :

Elle est pas mal cette fonction, mais vous oubliez un detail : dans une liste chainée, il peut arriver qu'un maillon soit pointé par deux pointeurs



Pas dans une liste linéaire classique...
 
 
C'est pas croyable comment on peut buter sur des problèmes "simples".
Finalement, elle a du bon l'approche récursive proposée au départ. Elle est pas boguée au moins, elle...
Je remarque cependant que puisqu'elle se protège du NULL, elle n'a pas pas besoin de protéger l'appel récursif:

Code :
  1. void efface(COMMANDES *com){
  2. if(com){
  3.  efface(com->suivant);
  4.  if(com->nom){
  5.   for(int n=0 ; com->nom[n] ; n++)
  6.    free(com->nom[n]);
  7.   free (com->nom);
  8.  }
  9.  free(com);
  10. }
  11. }


Ou alors, elle ne se protège pas, et protège la récursion:

Code :
  1. void efface(COMMANDES *com){
  2. if(com->suivant)
  3.  efface(com->suivant);
  4. if (com->nom){
  5.  for(int n=0 ; com->nom[n] ; n++)
  6.   free(com->nom[n]);
  7.  free (com->nom);
  8. }
  9. free(com);
  10. }


 
Autre chose à ajouter ?


Message édité par Musaran le 25-10-2002 à 05:05:17

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°234320
BifaceMcLe​OD
The HighGlandeur
Posté le 25-10-2002 à 10:46:01  profilanswer
 

Ouais : utiliser le design pattern "Collections" ! C'est possible y compris en C pur, et c'est fou, ce qu'on se fait moins ch...
 
edit> D'ailleurs, le topic "trouvez les bogues nn à nn" est fort intéressant, mais je trouve incroyable qu'on en soit encore là, alors qu'il existe depuis de nombreuses années des langages quasiment aussi efficaces que C++ du point de vue rapidité d'exécution, et infiniment plus sûrs du point de vue programmation (et je vous assure que le "infiniment" est pesé...)


Message édité par BifaceMcLeOD le 25-10-2002 à 10:48:51
n°234428
ddpforman
Posté le 25-10-2002 à 13:37:32  profilanswer
 

tu vas sur le site www.univ-artois.frr et tu envoies des mails à tous les profs d'info pour leur dire :-)

n°235286
Musaran
Cerveaulté
Posté le 26-10-2002 à 22:47:48  profilanswer
 

Je ne connais pas le design pattern "Collection"...
 
J'aurais une opinion sur les autres langages quand je les aurais essayés.
Concernant le C++, c'est clair qu'il mériterait une formulation moderne, débarassée des scories de son évolution.
Je suis moi-même impressionné de la facilité avec laquelle je peut caser plusieurs bogues par ligne !
 
Pour ceux que ça intéresserait, on cause ici:
http://www.codeguru.com/forum/show [...] did=213553 "Why Software Is So Bad?"


Message édité par Musaran le 26-10-2002 à 23:39:13

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  demande de validation d'une fonction en c avec des pointeurs

 

Sujets relatifs
[PHP] aidez moi à améliorer une fonction :( regex ?Instanciation d'une classe en fonction d'un type en C#
[XHTML 1.1] Problème de validationC koi le prob avec ma fonction ?
Site internet en creation, demande d'aide merci..[C] Petite question sur les pointeurs deux étoiles qui se suivent
Faire des liens en fonction de l'idValidation de formulaire en JS avec un lien... ça marche plus...
[PHP] un herbergeur avec la fonction mail, pas cherAffichage du code sous VC++ en fonction des directives preprocesseur
Plus de sujets relatifs à : demande de validation d'une fonction en c avec des pointeurs


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR