bug : donné qui change lors d'un retour de fonction

bug : donné qui change lors d'un retour de fonction - C - Programmation

Marsh Posté le 27-05-2006 à 01:36:53    

Bonsoir a tous!
 
Alors voila, j'ai un probleme... et je ne comprend vraiment pas!
 
J'ai une fonction qui lit un fichier texte et qui renvoi le resultat dans un tableau,alloué dynamiquement dans la fonction en question, avec les verifs necessaire (heu la il en manque sur le traitement des chaines apres mais c'est pas le probleme).
Lorsque j'ai sort de la fonction, j'ai donc tout un traitement qui s'en suit, mais j'ai remarqué que quelque valeur (generalement autour de 4  pour un tableau de 200 a 1000 element, changé radicalement! Ce que je n'explique pas...
Alors pour verif, j'ai afficher mon tableau avant et juste apres le retour, et j'ai constater que c'est la que les changements de valeur on lieu...
 
Alors ci quelqu'un avais une suggestion?? merci.
 
La fonction :  
 

Code :
  1. int** LireParametre(char* str)
  2. {
  3. FILE* f;
  4. int *tab=NULL;
  5. int ** res=NULL;
  6. int nb=0,i=0;
  7. char* strT=NULL;
  8. char* strT2=NULL;
  9. if( (strT=(char*)malloc(sizeof(char)*100)) ==NULL)
  10.  return NULL;
  11. if( (strT2=(char*)malloc(sizeof(char)*100))==NULL)
  12. {
  13.  free(strT);
  14.  return NULL;
  15. }
  16. if ((res=(int**)malloc(sizeof(int*)*2))==NULL)
  17. {
  18.  free(strT);
  19.  free(strT2);
  20.  return NULL;
  21. }
  22. if ((f=fopen(str,"r+" ))==NULL)
  23. {
  24.  free(strT);
  25.  free(strT2);
  26.  return NULL;
  27. }
  28. if ((tab=(int*)malloc(sizeof(int)*nb))==NULL)
  29. {
  30.  free(strT);
  31.  free(strT2);
  32.  return NULL;
  33. }
  34. fgets(strT,sizeof(char)*99,f);
  35. nb=atoi(strT);
  36. for(i=0;i<nb;i++)
  37. {
  38.  if (i==64)
  39.  {
  40.   i=64;
  41.  }
  42.  fgets(strT,sizeof(char)*99,f);
  43.  strT2=strtok(strT," " );
  44.  strT2=strtok(NULL," " );
  45.  tab[i]=atoi(strT2);
  46.  printf("%d ",tab[i]);
  47. }
  48. printf("\n\n" );
  49. res[0]=&nb;
  50. res[1]=tab;
  51. fclose(f);
  52. return res;
  53. }

Message cité 1 fois
Message édité par gargantua307 le 27-05-2006 à 01:49:37
Reply

Marsh Posté le 27-05-2006 à 01:36:53   

Reply

Marsh Posté le 27-05-2006 à 01:57:13    

Tu oublies des free et des fclose dans ta gestion des erreurs ;)
sizeof(char) est totalement inutile, sizeof(char) fait forcément 1, quelque soit la plateforme.
Les casts de tes mallocs sont inutiles voire nuisible, je te conseille de les virer.
A la ligne 45 , tu fais "si i égale 64 , alors i égale 64" [:pingouino]
Enfin dans res[0] tu met l'adresse d'une variable locale à ta fonction, quand tu quitte la fonction l'adresse n'est plus valide et tu te retrouve avec une valeur indéfinie à la place.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 27-05-2006 à 02:01:42    

0x90 a écrit :

Tu oublies des free et des fclose dans ta gestion des erreurs ;)
sizeof(char) est totalement inutile, sizeof(char) fait forcément 1, quelque soit la plateforme.
Les casts de tes mallocs sont inutiles voire nuisible, je te conseille de les virer.
A la ligne 45 , tu fais "si i égale 64 , alors i égale 64" [:pingouino]
Enfin dans res[0] tu met l'adresse d'une variable locale à ta fonction, quand tu quitte la fonction l'adresse n'est plus valide et tu te retrouve avec une valeur indéfinie à la place.


 
 
Tien oui, tu as raison pour le "nb"! L eplus etonnant est que ça marche :D
Mais j'v corrigé ;)
 
Heu pour le i=64 la, en faite c'est une lgine que j'avais ajouter pour m'arretter dans le debugger a une iteration precise ! et j'ai oublier de la virer :p
Sinon si je cast mes malloc c'est que j'export en c++ apres...

Reply

Marsh Posté le 27-05-2006 à 02:07:00    

Sous gdb tu peut déclarer des breakpoints conditionnels:

Code :
  1. break 45 if i==64


Sans altérer ton code, si t'utilise pas gdb tu dois surement avoir l'équivalent, c'est quand même plus esthétique que de modifier son code juste pour le debug.
 
Essaye pour ton problème de remplacer atoi par un strtol et de bien faire la vérification d'erreur ... (ce qu'atoi ne permet pas de faire)


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 27-05-2006 à 02:10:09    

Bah en faite je suis sous visual c++ et je debutte avec, donc j'paitrise pas trop le debugger encore.
 
Mais par contre atoi renvoie 0 en cas de probleme me semble t'il, ce qui ne me pose pas de probleme fondamentale.
bref, en tout cas l'erreur ne se situe pas ici, car losque j'affiche tout mon tableau (tab) dans la fonction, tout est ok, mais des que j'en sort : hop, certaines valeurs changent...:s !

Reply

Marsh Posté le 27-05-2006 à 08:30:51    

bug ici
   

Code :
  1. if ((tab=(int*)malloc(sizeof(int)*nb))==NULL)
  2.     {
  3.         free(strT);
  4.         free(strT2);
  5.         return NULL;
  6.     }   
  7.     fgets(strT,sizeof(char)*99,f);
  8.     nb=atoi(strT);

Tu fais l'allocation de tab avant de connaître la valeur de nb. c'est bizarre que ça foncitonne d'ailleurs puisque nb = 0.
Ton code est à jour ?

Reply

Marsh Posté le 27-05-2006 à 09:38:26    

Gérer les erreurs c'est bien... mais faut que ça soit complet.
Ligne 10: strT=malloc(...)
Ligne 13: si strT2=malloc(...) échoue
       libérer strT => ok
Ligne 19: si res=malloc(...) échoue
       libérer strT et strT2 => ok
Ligne 26: si f=fopen() échoue
       libérer strT et strt2 => et que fais-tu de "res" ???
Ligne 33: si tab=malloc(...) échoue
       libérer strT et strt2 => que fais-tu de "res" et de "f" ???


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 27-05-2006 à 10:18:36    

Une autre couche : à quoi sert d'allouer de la mémoire à strT2 puisqu'après tu fais strT2=strtok(strT," " ); ?

Citation :

L eplus etonnant est que ça marche  

Non, puisque c'est une adresse dans la pile, tu as n'importe quoi à cet endroit mais comme tu le traites comme un nombre tu as peu de risques d'avoir une erreur système à cet endroit, mais par contre de gros soucis pour savoir d'où vient le bug.

Reply

Marsh Posté le 27-05-2006 à 10:27:15    

Trap D a écrit :

...puisque c'est une adresse dans la pile, tu as n'importe quoi à cet endroit mais comme tu le traites comme un nombre tu as peu de risques d'avoir une erreur système à cet endroit, mais par contre de gros soucis pour savoir d'où vient le bug.


[:ddr555]


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 27-05-2006 à 11:01:06    

Moi y'a déjà un truc qui me choque, c'est l'utilisation des malloc().
Etant donné que toutes tes tailles sont connues à la compilation (100), pourquoi tu utilises malloc()?
Pour le plaisir d'utiliser le tas, ou d'avoir des fuites mémoire de partout?
 
Ensuite, quand on voit:

Code :
  1. tab=(int*)malloc(sizeof(int)*nb)


avec nb=0, je me dis que t'es suicidaire.
 

Reply

Marsh Posté le 27-05-2006 à 11:01:06   

Reply

Marsh Posté le 27-05-2006 à 11:05:20    

gargantua307 a écrit :

La fonction :  


 
Nous avons une Force 9 !

Message cité 2 fois
Message édité par Emmanuel Delahaye le 27-05-2006 à 11:06:06

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-05-2006 à 11:22:20    


 

Citation :


 Force 3
    * Indentation > 4 espaces


 
Ah bon?
http://lxr.linux.no/source/Documentation/CodingStyle
 
In short, 8-char indents make things easier to read, and have the added
benefit of warning you when you're nesting your functions too deep.
Heed that warning.
 

Citation :


 Force 4
 
    * Usage de TAB au lieu de SPACE  


Ah bon?
 
Outside of comments, documentation and except in Kconfig, spaces are never
used for indentation, and the above example is deliberately broken.
 

Citation :


 Force 6
 
    * Usage de TAB au lieu de SPACE  


Encore?
 
Mais surtout:
 

Citation :


 Force 10
 
    * Utilisation de goto (Code spaghetti)


 
C'est quoi cette idée?
Jette un coup d'oeil à ça:
 
http://kerneltrap.org/node/553/2131
 
Il ya beaucoup de hackers *très* compétents qui utilisent (à bon escient) goto.
 
D'ailleurs, quand tu utilises un if ou un switch, tu n'as pas l'impression d'utiliser goto?

Message cité 1 fois
Message édité par simple_stupid le 27-05-2006 à 11:31:26
Reply

Marsh Posté le 27-05-2006 à 12:00:11    


Ahah, je suis un force 8 au moins :D
- Tab au lieu d'espace, parceque comme ca chacun choisit d'afficher le code comme il lui plait, mais espaces pour les indentations "esthétiques" suplémentaires. (Cela dit c'est un troll séculaire, donc on va pas s'étendre dessus, mais justement ca m'étonne de le trouver dans ton échelle )
- Include de .c , j'ai un projet ou je le fais, mais le cas est relativement particulier, cela dit ddd n'arrive pas à les trouver lors du debug donc faudrait ptêtre que je trouve une solution :ange:
- Multiple return, bha euh, dans certains cas avec de nombreux points d'échec c'etait le plus clair à faire.
- Fonction de plus d'une page : c'est quoi une page exactement en nombre de lignes ? Puis selon le style d'indentation (crochet tout seul ou pas, par exemple) une même fonction va prendre 2x plus de place. (bon pour certains c'est une excellente raison de mettre les crochets sur la ligne du if...)


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 27-05-2006 à 12:15:32    

simple_stupid a écrit :

Il ya beaucoup de hackers *très* compétents qui utilisent (à bon escient) goto.


Moi je dis que les goto sont nos amis, qu'il faut les aimer aussi...
Vive le F.N.L.G => Front National de Libération des Goto
 :pt1cable:  


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 27-05-2006 à 12:19:06    

0x90 a écrit :


- Fonction de plus d'une page : c'est quoi une page exactement en nombre de lignes ? Puis selon le style d'indentation (crochet tout seul ou pas, par exemple) une même fonction va prendre 2x plus de place. (bon pour certains c'est une excellente raison de mettre les crochets sur la ligne du if...)


Une page ANSI fait 25 lignes sur 80 colonnes.
Généralement, une fonction ne doit pas excéder 2 pages, donc 50 lignes.
Pour la même raison, le nombre de colonnes ne doit pas excéder 80 caractères de large (quand tu codes  comme moi en console, tu comprends vite pourquoi).
 
Bon, après ce ne sont que des recommandations, mais étant donné qu'un code est destiné à être compris par autrui, autant s'y tenir.
 
Mais comme tu le soulignes, entre le style gnu et le K&R, y'a pas mal de différences.
Mais, comme on dit:
1) K&R are right
2) K&R *are* right
 

Citation :


Moi je dis que les goto sont nos amis, qu'il faut les aimer aussi...
Vive le F.N.L.G => Front National de Libération des Goto
 :pt1cable:  


Ah, enfin un mec bien ;-)
 
Non, mais ce serait vraiment idiot de ne pas s'en servir, parfois c'est ce qu'il y a de mieux à faire.

Message cité 2 fois
Message édité par simple_stupid le 27-05-2006 à 12:20:39
Reply

Marsh Posté le 27-05-2006 à 12:30:34    

simple_stupid a écrit :

Ah, enfin un mec bien ;-)


J'entretiens d'ailleurs une correspondance régulière avec un petit goto des pays lointains.
Parfois, il me dit qu'il se sent seul, pas aimé, inutile. et là, je lui réponds

Citation :

Non, ami, tu n'es pas seul, non, ami, tu n'es pas inutile. Il y a, là bas, loin de toi en France, tout un tas de gens qui t'aiment et qui respectent ton action


Là, il me répond en souriant "tu es un frère".
C'est vrai, je vous le dit, je me sens frère de tous les "goto" du monde entier...
 :pt1cable:  :pt1cable:  :pt1cable:  


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 27-05-2006 à 12:33:33    

simple_stupid a écrit :

Une page ANSI fait 25 lignes sur 80 colonnes.
Généralement, une fonction ne doit pas excéder 2 pages, donc 50 lignes.
Pour la même raison, le nombre de colonnes ne doit pas excéder 80 caractères de large (quand tu codes  comme moi en console, tu comprends vite pourquoi).
 
Bon, après ce ne sont que des recommandations, mais étant donné qu'un code est destiné à être compris par autrui, autant s'y tenir.
 
Mais comme tu le soulignes, entre le style gnu et le K&R, y'a pas mal de différences.
Mais, comme on dit:
1) K&R are right
2) K&R *are* right


Le 80 colonne je respecte ;) J'aime pas que ca aille à la ligne tout seul avec un look bizarre.
les lignes bha, disons que je fais pas TROP long dans le sens ou ca deviendrait incompréhensible à suivre de bout en bout, mais je regarde pas précisément non plus.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 27-05-2006 à 13:23:13    

Pour info :  
 
 
le malloc avec le nb=0 c'etais une erreur de copié coller quand j'ai modif mon code, c'etais bien apres l'initialisation de nb! ^_^ J'ai corrigé ça se matin.
 
 
Sinon concernant l'erreur que j'avais, j'ai changé l'erreur du "nb" qui etais en local et ça m'a resolut le probleme des modifs en mémoire.
 
bon, sinon j'ai refait un peu de propre dans ce code qui data un peu :p
 
 
merci a vous

Reply

Marsh Posté le 27-05-2006 à 13:34:35    

Sve@r a écrit :

J'entretiens d'ailleurs une correspondance régulière avec un petit goto des pays lointains.
Parfois, il me dit qu'il se sent seul, pas aimé, inutile. et là, je lui réponds

Citation :

Non, ami, tu n'es pas seul, non, ami, tu n'es pas inutile. Il y a, là bas, loin de toi en France, tout un tas de gens qui t'aiment et qui respectent ton action


Là, il me répond en souriant "tu es un frère".
C'est vrai, je vous le dit, je me sens frère de tous les "goto" du monde entier...
 :pt1cable:  :pt1cable:  :pt1cable:

Amen  
http://www.stacken.kth.se/~foo/weekpics/goto.jpg


Message édité par Trap D le 27-05-2006 à 13:35:06
Reply

Marsh Posté le 27-05-2006 à 13:36:04    


 
D'ailleur en parlant de goto, avec un ami on a fondé le FLGT : Fron de Liberation du GoTo ! :p
 
(veridique mais pas officiel)

Reply

Marsh Posté le 29-05-2006 à 22:05:21    

Citation :

simple_stupid a dit :
C'est quoi cette idée?
Jette un coup d'oeil à ça:
 
http://kerneltrap.org/node/553/2131
 
Il ya beaucoup de hackers *très* compétents qui utilisent (à bon escient) goto.
 
D'ailleurs, quand tu utilises un if ou un switch, tu n'as pas l'impression d'utiliser goto?


 
alors là... j'en tombe de ma chaise...comme koi, les pinguins ne font pas que des conneries, ils en ecrivent aussi :Þ
 
moi j'dis "sus mes braves, mort au goto !!"

Reply

Marsh Posté le 29-05-2006 à 22:31:56    

pfuitt a écrit :

Citation :

simple_stupid a dit :
C'est quoi cette idée?
Jette un coup d'oeil à ça:
 
http://kerneltrap.org/node/553/2131
 
Il ya beaucoup de hackers *très* compétents qui utilisent (à bon escient) goto.
 
D'ailleurs, quand tu utilises un if ou un switch, tu n'as pas l'impression d'utiliser goto?


 
alors là... j'en tombe de ma chaise...comme koi, les pinguins ne font pas que des conneries, ils en ecrivent aussi :Þ
 
moi j'dis "sus mes braves, mort au goto !!"


Avec quelle justification exactement ?


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 29-05-2006 à 22:35:07    

0x90 a écrit :

Avec quelle justification exactement ?


Comme d'habitude.
Linux c'est dur, lent, pour les root, écrit par des barbus, et y'a pas msn.
 
Nan, c'est pas ça.
 
(Je tourne sous Debian, hein)

Reply

Marsh Posté le 29-05-2006 à 22:36:17    

simple_stupid a écrit :

Comme d'habitude.
Linux c'est dur, lent, pour les root, écrit par des barbus, et y'a pas msn.
 
Nan, c'est pas ça.
 
(Je tourne sous Debian, hein)


Nan mais à propos de linux j'en ai rien à foutre de son avis, c'etait à propos du goto seulement.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 31-05-2006 à 21:48:35    

0x90 a écrit :

Nan mais à propos de linux j'en ai rien à foutre de son avis, c'etait à propos du goto seulement.


 
le goto ?
franchement je trouve que ca 'destructure' le code... mais ce n'est que mon avis perso...d'un autre coté, si on peut pas le donner sur un forum, là, y'a un soucy comme dit l'autre!
je pense que ca doit etre une reminiscence de mes debuts en codage et puis un code avec plein de jolies fonctions et tout et tout c'est vachement plus lisible, nan?
après, si on rentre dans les détails, il y a surement des arguments imparables... mais bon, j'm'y fais pas ! j'm'y fait pas, me jetter pas la pierre !!

Reply

Marsh Posté le 31-05-2006 à 21:53:52    

faut arreter, le goto c'est mal d'en abuser, mais il y a des (rares) cas ou ca simplifie le code

Reply

Marsh Posté le 31-05-2006 à 22:04:27    

skelter a écrit :

le goto c'est mal d'en abuser


En fait, c'est mal d'abuser de quoi que ce soit. Chaque mécanisme a des avantages et des inconvénients et en abuser arrive souvent à ce qu'on ait plus d'inconvénients que d'avantage...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 31-05-2006 à 22:10:32    

oui  :jap:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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