[C] fonction free

fonction free [C] - C - Programmation

Marsh Posté le 01-12-2005 à 11:49:31    

Salut à tous !
 
J'ai un petit problème avec la fonction free, je fais un programme qui doit trouver une solution à une formule de logique de la forme (a|b)&(c|d)&...
j'ai décidé de travailler avec des string (peut etre pas la meilleur solution)...
enfin bon, tous mes free marchent correctement, à part 1 qui ne passe pas ("Program received signal SIGSEGV, Segmentatioàn fault. 0x001f03d4 in _int_free () from /lib/tls/libc.so.6" )
J'aimerai savoir d'ou peut provenir une erreur de ce genre.
j'utilise calloc pour allouer, j'initialise mon string avec des '\0' .
Si je fais p str dans gdb juste avant la seg fault il me sort bien mon expression ...
Bref help me pleaz :(
Merci!
a+

Reply

Marsh Posté le 01-12-2005 à 11:49:31   

Reply

Marsh Posté le 01-12-2005 à 11:52:40    

Paste ton code, ce sera plus simple

Reply

Marsh Posté le 01-12-2005 à 11:58:07    

hum il y a 683 lignes de code :/

Reply

Marsh Posté le 01-12-2005 à 12:26:43    

alors isole le problème

Reply

Marsh Posté le 01-12-2005 à 12:27:05    

char* maj(char* algo,char c,int oui)
{
  char *membre,*tmp;
  unsigned int i=0,j,m,compte1=0,compte2=0,a;
  // supprimes les membres contenant le char c.
  while((algo[i]!='\0')&&(algo[0]!='\0'))
    {
      m=0;
      if(algo[i]=='&') i++;
      membre=copymembre(algo,i);
      for(j=0;j<strlen(membre);j++)
 {
   if(((membre[j]==c)&&(membre[j-1]!='!')&&(oui==1))||
      ((membre[j]==c)&&(membre[j-1]=='!')&&(oui==0)))
     {
       algo=supprmembr(membre,algo);
       i=0;
       m=1;
     }
 }
      if(m==0) i=i+strlen(membre);
      init(membre,strlen(membre));
      free(membre);
    }
  i=0;
  m=0;
  // compte les membres.
  membre=copymembre(algo,i);
  if(membre[0]!='\0')
  do
    {
      i=i+strlen(membre);
      if(algo[i]=='&') i++;
      compte1++;
      init(membre,strlen(membre));
      free(membre);
      membre=copymembre(algo,i);
    }while((i==0)||(membre[0]!='\0'));
  i=0;
  a=strlen(algo);
  while(algo[i]!='\0')
    {
      // supprimes les membres opposé aux membres validé (ex: si c = a, on supprimera tous les !a)
      if((algo[i]==c)&&(((oui==0)&&(algo[i-1]!='!'))
        ||((oui==1)&&(algo[i-1]=='!'))))
 {
   j=i+1;
   if(((algo[i+1]==')'))&&((algo[i-1]=='(')||(algo[i-2]=='(')))
     {
       if(algo[i-2]=='(')
  {
    j=i+2;
    i=i-3;
  }
       else
  {
    j=i+2;
    i=i-3;
  }
     }
   else if(oui==1) i=i-1;  
   if(algo[j+1]=='\0') i=i-1;
   else
   while((avanexpr(algo[j]))&&(algo[j]!='!')) j++;
   while(algo[j]!='\0')  
     {
       algo[i]=algo[j];
       i++;
       j++;
     }
   while(i<a)  
     {
       algo[i]='\0';
       i++;
     }
   m=1;
        }
      i++;
      if(m==1) i=0;
      m=0;
    }
  i=0;
  init(membre,strlen(membre));
  // recompte les membres
  free(membre);
  membre=copymembre(algo,i);
  i=i+strlen(membre);
  if(membre[0]!='\0')
  do
    {
      compte2++;
      if(algo[i]=='&') i++;
      init(membre,strlen(membre));
      free(membre);
      membre=copymembre(algo,i);
      i=i+strlen(membre);
    }while((i==0)||(membre[0]!='\0'));
  init(membre,strlen(membre));
  free(membre);
  if(compte1!=compte2)
    {
/* si les 2 nombres sont pas égaux alors un membre a disparu ce qui n'est pas correct.
ex: pour (a|b)&(c|d)&(d|e|f)&(!c|!d)&(a)&(!e|!f) l'algorithme de davis putmann va inclure (a) dans (a|b) donc (a|b) va disparaitre. ensuite il va trouver (a) comme membre seul et va le valider. aucune suppression dans la fonction maj. puis le programme ne va ni trouver de membre seul, ni de membre unique(présent dans un seul état (ex: que des (a) ou des (!a) dans l'expression)) donc va parcourrir un arbre. A ce moment là il va prendre la premiere lettre rencontrer (donc c si dessous vu que (a|b) a disparu) et va valider c. l'expression sera donc: (d|e|f)&(!d)&(!e|!f). arbre va se lancer recursivement et va faire la même chose sur la nouvelle expression. cette fois ci le premier membre est d, donc il va executer d. (d|e|f) disparait, mais dans maj il supprime (!d) vu qu'on a validé d, donc le programme doit normalement revenir en arriere est testé e désormais, mais quand j'essaie de faire free sur le nouvel algo qui est faux(dans maj apres avoir supprimer le !d) il me fait l'erreur */
 
      printf("pas de solution\n" );
      tmp=algo;
      algo=calloc(6,sizeof(char));
      init(algo,6);
      strcpy(algo,"error" );
      algo[5]='\0';
     
      free(tmp);  ==> seg fault
 
    }
   
  return algo;
}
 
 
char* arbre(char *algo,char reponse[],int *j)
{
  // trouves une solution à l'algo entré, reponse[] contient les lettres déjà validé, j-1 pointe la derniere reponse trouvé.  
  unsigned int i=0,e=0,k;
  char *membre,*test;
  // on copie le premier membre, sur l'exemple on copiera (c|d) la premiere fois
  membre=copymembre(algo,i);
  // on le supprime directement: (c|d) doit être impérativement validé.
  algo=supprmembr(membre,algo);
  // création d'un clone de algo.
  test=calloc(strlen(algo)+1,sizeof(char));
  init(test,strlen(algo)+1);
  strcpy(test,algo);
  while(membre[i]!='\0')
    {
      while(avanexpr(membre[i])) i++;
      k=i;
      if(membre[i]=='\0') break;
      if((i>0)&&(test[i-1]=='!'))
 {
          // mise a jour de test avec le membre[i] (c'est à dire c a l'origine). si l'algo n'est plus valide test contiendra "erreur".
   test=maj(test,membre[i],0);
 }
      if(algo[i-1]!='!')
 {
// meme chose pour le cas ou c'est un a et non un !a
   test=maj(test,membre[i],1);
 }
      if(strcmp(test,"error" )!=0)
      // si test n'a pas rapporté d'erreur, on continue à parcourrir l'arbre.
 {
   printf("arbre\n" );
   if((i>0)&&(membre[i-1]=='!'))
     {
            // on note la réponse.
       reponse[*j]=membre[i-1];
       reponse[*j+1]=membre[i];
       *j=*j+2;
       e=0;
       if(test[0]=='\0') break;
       i=i+strlen(membre);
       free(membre);
              // on relance arbre avec le nouvel algo.
       test=arbre(test,reponse,j);
     }
   if(membre[i-1]!='!')
     {
            // meme chose pour a ...
       reponse[*j]=membre[i];
       *j=*j+1;
       e=0;
       if(test[0]=='\0') break;
       i=i+strlen(membre);
       init(membre,strlen(membre));
       free(membre);
       test=arbre(test,reponse,j);
     }
          // si le programme rapporte une erreur, on met e à 1 et on sort de la boucle.          
          on renvoit donc erreur au programme precedent.
   if(strcmp(test,"error" )==0)
     {
       e=1;
       break;
     }
 }
      // si le string contient une erreur, on reinitialise algo, et on incremente i pour tester un autre membre.  
      else
 {
   init(test,strlen(algo));
   i=k+1;
   strcpy(test,algo);
   e=1;
 }
    }
  if(e==1)
    {
      strcpy(test,"error" );
    }
  init(membre,strlen(membre));
  free(membre);
  return test;
}

Reply

Marsh Posté le 01-12-2005 à 12:36:25    

precision:
algo contient l'ensemble de l'expression
copymembre copy le membre a partir de i jusqu'à rencontrer un & ou un \0.

Reply

Marsh Posté le 01-12-2005 à 12:39:56    

arg les intervalles sont pas respectés ca va être la misere pour lire le code :(

Reply

Marsh Posté le 01-12-2005 à 12:51:00    

précise rien du tout : tu trouves les 5 méchantes lignes, on va pas lire un paté comme ça.

Reply

Marsh Posté le 01-12-2005 à 13:13:16    

Taz a écrit :

alors isole le problème


 

cloudddd a écrit :

char* maj(char* algo,char c,int oui)
{
  char *membre,*tmp;
  unsigned int i=0,j,m,compte1=0,compte2=0,a;
  // supprimes les membres contenant le char c.
  while((algo[i]!='\0')&&(algo[0]!='\0'))
    {
      m=0;
      if(algo[i]=='&') i++;
      membre=copymembre(algo,i);
      for(j=0;j<strlen(membre);j++)
 {
   if(((membre[j]==c)&&(membre[j-1]!='!')&&(oui==1))||
      ((membre[j]==c)&&(membre[j-1]=='!')&&(oui==0)))
     {
       algo=supprmembr(membre,algo);
       i=0;
       m=1;
     }
 }
      if(m==0) i=i+strlen(membre);
      init(membre,strlen(membre));
      free(membre);
    }
  i=0;
  m=0;
  // compte les membres.
  membre=copymembre(algo,i);
  if(membre[0]!='\0')
  do
    {
      i=i+strlen(membre);
      if(algo[i]=='&') i++;
      compte1++;
      init(membre,strlen(membre));
      free(membre);
      membre=copymembre(algo,i);
    }while((i==0)||(membre[0]!='\0'));
  i=0;
  a=strlen(algo);
  while(algo[i]!='\0')
    {
      // supprimes les membres opposé aux membres validé (ex: si c = a, on supprimera tous les !a)
      if((algo[i]==c)&&(((oui==0)&&(algo[i-1]!='!'))
        ||((oui==1)&&(algo[i-1]=='!'))))
 {
   j=i+1;
   if(((algo[i+1]==')'))&&((algo[i-1]=='(')||(algo[i-2]=='(')))
     {
       if(algo[i-2]=='(')
  {
    j=i+2;
    i=i-3;
  }
       else
  {
    j=i+2;
    i=i-3;
  }
     }
   else if(oui==1) i=i-1;  
   if(algo[j+1]=='\0') i=i-1;
   else
   while((avanexpr(algo[j]))&&(algo[j]!='!')) j++;
   while(algo[j]!='\0')  
     {
       algo[i]=algo[j];
       i++;
       j++;
     }
   while(i<a)  
     {
       algo[i]='\0';
       i++;
     }
   m=1;
        }
      i++;
      if(m==1) i=0;
      m=0;
    }
  i=0;
  init(membre,strlen(membre));
  // recompte les membres
  free(membre);
  membre=copymembre(algo,i);
  i=i+strlen(membre);
  if(membre[0]!='\0')
  do
    {
      compte2++;
      if(algo[i]=='&') i++;
      init(membre,strlen(membre));
      free(membre);
      membre=copymembre(algo,i);
      i=i+strlen(membre);
    }while((i==0)||(membre[0]!='\0'));
  init(membre,strlen(membre));
  free(membre);
  if(compte1!=compte2)
    {
/* si les 2 nombres sont pas égaux alors un membre a disparu ce qui n'est pas correct.
ex: pour (a|b)&(c|d)&(d|e|f)&(!c|!d)&(a)&(!e|!f) l'algorithme de davis putmann va inclure (a) dans (a|b) donc (a|b) va disparaitre. ensuite il va trouver (a) comme membre seul et va le valider. aucune suppression dans la fonction maj. puis le programme ne va ni trouver de membre seul, ni de membre unique(présent dans un seul état (ex: que des (a) ou des (!a) dans l'expression)) donc va parcourrir un arbre. A ce moment là il va prendre la premiere lettre rencontrer (donc c si dessous vu que (a|b) a disparu) et va valider c. l'expression sera donc: (d|e|f)&(!d)&(!e|!f). arbre va se lancer recursivement et va faire la même chose sur la nouvelle expression. cette fois ci le premier membre est d, donc il va executer d. (d|e|f) disparait, mais dans maj il supprime (!d) vu qu'on a validé d, donc le programme doit normalement revenir en arriere est testé e désormais, mais quand j'essaie de faire free sur le nouvel algo qui est faux(dans maj apres avoir supprimer le !d) il me fait l'erreur */
 
      printf("pas de solution\n" );
      tmp=algo;
      algo=calloc(6,sizeof(char));
      init(algo,6);
      strcpy(algo,"error" );
      algo[5]='\0';
     
      free(tmp);  ==> seg fault
 
    }
   
  return algo;
}
 
 
char* arbre(char *algo,char reponse[],int *j)
{
  // trouves une solution à l'algo entré, reponse[] contient les lettres déjà validé, j-1 pointe la derniere reponse trouvé.  
  unsigned int i=0,e=0,k;
  char *membre,*test;
  // on copie le premier membre, sur l'exemple on copiera (c|d) la premiere fois
  membre=copymembre(algo,i);
  // on le supprime directement: (c|d) doit être impérativement validé.
  algo=supprmembr(membre,algo);
  // création d'un clone de algo.
  test=calloc(strlen(algo)+1,sizeof(char));
  init(test,strlen(algo)+1);
  strcpy(test,algo);
  while(membre[i]!='\0')
    {
      while(avanexpr(membre[i])) i++;
      k=i;
      if(membre[i]=='\0') break;
      if((i>0)&&(test[i-1]=='!'))
 {
          // mise a jour de test avec le membre[i] (c'est à dire c a l'origine). si l'algo n'est plus valide test contiendra "erreur".
   test=maj(test,membre[i],0);
 }
      if(algo[i-1]!='!')
 {
// meme chose pour le cas ou c'est un a et non un !a
   test=maj(test,membre[i],1);
 }
      if(strcmp(test,"error" )!=0)
      // si test n'a pas rapporté d'erreur, on continue à parcourrir l'arbre.
 {
   printf("arbre\n" );
   if((i>0)&&(membre[i-1]=='!'))
     {
            // on note la réponse.
       reponse[*j]=membre[i-1];
       reponse[*j+1]=membre[i];
       *j=*j+2;
       e=0;
       if(test[0]=='\0') break;
       i=i+strlen(membre);
       free(membre);
              // on relance arbre avec le nouvel algo.
       test=arbre(test,reponse,j);
     }
   if(membre[i-1]!='!')
     {
            // meme chose pour a ...
       reponse[*j]=membre[i];
       *j=*j+1;
       e=0;
       if(test[0]=='\0') break;
       i=i+strlen(membre);
       init(membre,strlen(membre));
       free(membre);
       test=arbre(test,reponse,j);
     }
          // si le programme rapporte une erreur, on met e à 1 et on sort de la boucle.          
          on renvoit donc erreur au programme precedent.
   if(strcmp(test,"error" )==0)
     {
       e=1;
       break;
     }
 }
      // si le string contient une erreur, on reinitialise algo, et on incremente i pour tester un autre membre.  
      else
 {
   init(test,strlen(algo));
   i=k+1;
   strcpy(test,algo);
   e=1;
 }
    }
  if(e==1)
    {
      strcpy(test,"error" );
    }
  init(membre,strlen(membre));
  free(membre);
  return test;
}


 
 [:skylight]  

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed