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

  FORUM HardWare.fr
  Programmation
  C

  Printf qui change le résultat d'un programme ??

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Printf qui change le résultat d'un programme ??

n°2181821
alexanonym​ous
Posté le 22-03-2013 à 14:50:55  profilanswer
 

Bonsoir,
J'ai l'impression d'avoir un problème venu d'un autre monde ! Selon que je laisse ou que j'enlève un printf (en le mettant en commentaire par exemple), le résultat de mon programme change !
Je vous donne le code mais je ne pense pas que ça soit très utile.
Le résultat final devrait être 0 1 0 2 1, mais de temps en temps, j'ai des résultats bizarres avec des -1...
Encore une fois, c'est peut-être pas la peine de se jeter dans le code, surtout qu'il n'est pas commenté.
Ce en quoi vous pourriez m'aider, c'est me dire par exemple si chez vous aussi, en mettant EN METTANT EN COMMENTAIRE OU NON la ligne 116, le résultat change (la ligne afficher_matrice(*domaine, N, D); )
Vous pourriez aussi me dire dans quelles circonstances un simple printf peut changer un résultat ! Je prends l'exemple de cette ligne mais je pense que je peux arriver à des résultats bizarres en laissant / enlevant d'autres lignes ! (ce qui m'est arrivé d'ailleurs).
Merci d'avance de votre aide ! ;)

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 5 // Nombre de variables : 0 -> N-1
  4. #define M 6 // Nombre de contraintes
  5. #define D 3 // Taille des données : 0 -> D-1
  6. typedef struct matrice {
  7.     int mat[100][100];
  8. } matrice ;
  9. /* ---------------------------------------------
  10. *
  11. * FONCTIONS DE GESTION DES MATRICES ET TABLEAUX
  12. *
  13. * --------------------------------------------- */
  14. void init_matrice (matrice *m, int hauteur, int largeur, int valeur)
  15. {
  16.     int i,j;
  17.     for (i=0; i<hauteur; i++)
  18.         for(j=0; j<largeur; j++) {
  19.             m->mat[i][j]=valeur;
  20.         }
  21. }
  22. void init_matrice_pointeurs (matrice *m[N][N])
  23. {
  24.     int i,j;
  25.     for (i=0; i<N; i++)
  26.         for(j=0; j<N; j++) {
  27.             m[i][j]=NULL;
  28.         }
  29. }
  30. void affecter_interpretation(int interpretation[N])
  31. {
  32.     int i;
  33.     for (i=0; i<N; i++) {
  34.         interpretation[i]=-1;
  35.     }
  36. }
  37. void afficher_etat_matrice_pointeurs (matrice *matrice_pointeurs [N][N])
  38. {
  39.     int i,j;
  40.     for (i=0; i<N; i++) {
  41.         for (j=0; j<N; j++) {
  42.             if (matrice_pointeurs[i][j]==NULL) {
  43.                 printf("Null " );
  44.             } else {
  45.                 printf("Matrice " );
  46.             }
  47.         }
  48.         printf("\n" );
  49.     }
  50. }
  51. void afficher_interpretation (int interpretation[N])
  52. {
  53.     int i;
  54.     for (i=0; i<N; i++) {
  55.         printf("%d ", interpretation[i]);
  56.     }
  57.     printf("\n" );
  58. }
  59. void afficher_matrice (matrice m, int hauteur, int largeur)
  60. {
  61.     int i,j;
  62.     for(i=0; i<hauteur; i++) {
  63.         for(j=0; j<largeur; j++) {
  64.             printf("%d ", m.mat[i][j]);
  65.         }
  66.         printf("\n" );
  67.     }
  68. }
  69. /* -----------------------------------------------------------
  70. *
  71. * FONCTION D'AFFECTATIONS DES VALEURS AU PROBLÈME DES GRAPHES
  72. *
  73. * ----------------------------------------------------------- */
  74. void couleur_graphe (matrice *domaine, matrice *matrice_pointeurs[N][N])
  75. {
  76.     matrice contraintes[M];
  77.     init_matrice (domaine, N, D, 1);
  78.     init_matrice_pointeurs(matrice_pointeurs);
  79.     int i;
  80.     for (i=0; i<M; i++) {
  81.         init_matrice (&contraintes[i], D, D, 1);
  82.     }
  83.     int j;
  84.     for (i=0; i<M; i++) {
  85.         for(j=0; j<D; j++) {
  86.             contraintes[i].mat[j][j]=0;
  87.         }
  88.         printf("La contrainte qui vient d'être créée est :\n" );
  89.         afficher_matrice(contraintes[i], D, D);
  90.         printf("\n" );
  91.     }
  92.     printf("\n\n\n" );
  93. // matrice_pointeurs[0][1]= (matrice *) malloc(sizeof(matrice *));
  94.     matrice_pointeurs[0][1]=&contraintes[0];
  95. // matrice_pointeurs[0][4]= (matrice *) malloc(sizeof(matrice *));
  96.     matrice_pointeurs[0][4]=&contraintes[1];
  97. // matrice_pointeurs[1][2]= (matrice *) malloc(sizeof(matrice *));
  98.     matrice_pointeurs[1][2]=&contraintes[2];
  99. // matrice_pointeurs[1][3]= (matrice *) malloc(sizeof(matrice *));
  100.     matrice_pointeurs[1][3]=&contraintes[3];
  101. // matrice_pointeurs[2][3]= (matrice *) malloc(sizeof(matrice *));
  102.     matrice_pointeurs[2][3]=&contraintes[4];
  103. // matrice_pointeurs[3][4]= (matrice *) malloc(sizeof(matrice *));
  104.     matrice_pointeurs[3][4]=&contraintes[5];
  105. }
  106. /* ----------------------------------
  107. *
  108. * IMPLÉMENTATION DU FORWARD CHECKING
  109. *
  110. * ---------------------------------- */
  111. void FC (matrice *domaine, matrice * matrice_pointeurs [N][N], int interpretation[N])
  112. {
  113.     matrice tmp;
  114.     int i,j,k,l;
  115.     for(i=0; i<N; i++) {
  116. // afficher_matrice(*domaine, N, D); // <== CETTE DE LIGNE !
  117.         for(j=0; j<D && interpretation[i]==-1; j++) {
  118.             if (domaine->mat[i][j]==1) {
  119.                 interpretation[i]=j;
  120.                 for(k=0; k<N; k++) {
  121.                     if (matrice_pointeurs[i][k]->mat!=NULL) {
  122.                         printf("i = %d, j = %d, k = %d\n", i, j, k);
  123.                         int c1, c2;
  124.                         for(c1=0 ; c1<D; c1++)
  125.                             for(c2=0 ; c2<D; c2++) {
  126.                                 tmp.mat[c1][c2]=matrice_pointeurs[i][k]->mat[c1][c2];
  127.                             }
  128. // printf("\nContraintes :\n" );
  129. // afficher_matrice(*matrice_pointeurs[i][k], D, D);
  130. // printf("\nFincontraintes\n" );
  131.                         for(l=0; l<D; l++) {
  132.                             if (tmp.mat[j][l]==0) {
  133.                                 domaine->mat[k][l]=0;
  134.                             }
  135.                         }
  136.                     }
  137.                 }
  138.             }
  139.         }
  140.         if (interpretation[i]==-1) {
  141.             printf("Fail !\n" );
  142.         }
  143.         /*
  144.         if (j==D)
  145.         BT*/
  146.     }
  147. }
  148. int main ()
  149. {
  150.     matrice domaine, *matrice_pointeurs[N][N];
  151.     couleur_graphe(&domaine, matrice_pointeurs);
  152.     afficher_etat_matrice_pointeurs(matrice_pointeurs);
  153.     int interpretation[N];
  154.     affecter_interpretation (interpretation);
  155.     FC (&domaine, matrice_pointeurs, interpretation);
  156.     printf("\n" );
  157.     afficher_matrice(domaine, N, D);
  158.     printf("\n" );
  159.     afficher_interpretation(interpretation);
  160.     return EXIT_SUCCESS;
  161. }


Message édité par alexanonymous le 23-03-2013 à 01:40:47
mood
Publicité
Posté le 22-03-2013 à 14:50:55  profilanswer
 

n°2181828
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 22-03-2013 à 15:16:25  profilanswer
 

Ma première idée, c'est que tu accèdes à/écrit des valeurs non initialisées (via un accès mal fait à un tableau par exemple). Du coup l'utilisation d'un printf peut changer pas mal de choses en mémoire et arranger ou empirer ta situation.
 
Passe un coup de valgrind :o


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
n°2181959
alexanonym​ous
Posté le 23-03-2013 à 02:05:02  profilanswer
 

Tout d'abord merci de cette réponse rapide, et merci à la personne qui a édité mon message pour rendre mon code lisible ! Le copier-coller avait fait des dégâts...
Bref, je connaissais pas Valgrind, mais après installation et lancement de la commande "valgrind ./programme" (dois-je rajouter des options pour être plus précis ?), j'ai ceci :
Je ne saurais pas du tout l'interpréter !
 
 
==2443== Memcheck, a memory error detector
==2443== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==2443== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==2443== Command: ./test
==2443==  
Null Matrice Null Null Matrice  
Null Null Matrice Matrice Null  
Null Null Null Matrice Null  
Null Null Null Null Matrice  
Null Null Null Null Null  
i = 0, j = 0, k = 1
==2443== Invalid read of size 4
==2443==    at 0x8048809: FC (in /home/alex/Bureau/test)
==2443==    by 0x804892A: main (in /home/alex/Bureau/test)
==2443==  Address 0xbe84fff0 is not stack'd, malloc'd or (recently) free'd
==2443==  
i = 0, j = 0, k = 4
i = 1, j = 1, k = 2
i = 1, j = 1, k = 3
i = 2, j = 0, k = 3
i = 3, j = 2, k = 4
==2443== Conditional jump or move depends on uninitialised value(s)
==2443==    at 0x804884B: FC (in /home/alex/Bureau/test)
==2443==    by 0x804892A: main (in /home/alex/Bureau/test)
==2443==  
 
1 1 1  
0 1 1  
1 0 1  
0 0 1  
0 1 0  
 
0 1 0 2 1  
==2443==  
==2443== HEAP SUMMARY:
==2443==     in use at exit: 0 bytes in 0 blocks
==2443==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==2443==  
==2443== All heap blocks were freed -- no leaks are possible
==2443==  
==2443== For counts of detected and suppressed errors, rerun with: -v
==2443== Use --track-origins=yes to see where uninitialised values come from
==2443== ERROR SUMMARY: 48 errors from 2 contexts (suppressed: 0 from 0)
 
 
==> Ca, c'est quand je lance avec la fameuse ligne commentée. C'est à dire que j'ai le résultat attendu, comme quand "j'exécute" mon code à la main (0 1 0 2 1)
Maintenant, en non commenté, ça donne ça, le mauvais résultat (et quelques affichages de matrices en plus) :
 
 
==2459== Memcheck, a memory error detector
==2459== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==2459== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==2459== Command: ./test
==2459==  
Null Matrice Null Null Matrice  
Null Null Matrice Matrice Null  
Null Null Null Matrice Null  
Null Null Null Null Matrice  
Null Null Null Null Null  
1 1 1  
1 1 1  
1 1 1  
1 1 1  
1 1 1  
i = 0, j = 0, k = 1
==2459== Invalid read of size 4
==2459==    at 0x804883F: FC (in /home/alex/Bureau/test)
==2459==    by 0x8048960: main (in /home/alex/Bureau/test)
==2459==  Address 0xbe974ff0 is not stack'd, malloc'd or (recently) free'd
==2459==  
i = 0, j = 0, k = 4
1 1 1  
0 1 1  
1 1 1  
1 1 1  
0 1 1  
i = 1, j = 1, k = 2
i = 1, j = 1, k = 3
1 1 1  
0 1 1  
1 0 1  
1 0 1  
0 1 1  
i = 2, j = 0, k = 3
==2459== Conditional jump or move depends on uninitialised value(s)
==2459==    at 0x8048881: FC (in /home/alex/Bureau/test)
==2459==    by 0x8048960: main (in /home/alex/Bureau/test)
==2459==  
1 1 1  
0 1 1  
1 0 1  
0 0 0  
0 1 1  
Fail !
1 1 1  
0 1 1  
1 0 1  
0 0 0  
0 1 1  
 
1 1 1  
0 1 1  
1 0 1  
0 0 0  
0 1 1  
 
0 1 0 -1 1  
==2459==  
==2459== HEAP SUMMARY:
==2459==     in use at exit: 0 bytes in 0 blocks
==2459==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==2459==  
==2459== All heap blocks were freed -- no leaks are possible
==2459==  
==2459== For counts of detected and suppressed errors, rerun with: -v
==2459== Use --track-origins=yes to see where uninitialised values come from
==2459== ERROR SUMMARY: 39 errors from 2 contexts (suppressed: 0 from 0)

n°2181960
Farian
Posté le 23-03-2013 à 02:24:46  profilanswer
 

Bonjour !
 
Votre problème de variable non initialisée est toujours présent, que vous incluiez la ligne avec le "printf" ou non, et valgrind la met en évidence dans tous les cas (ce qui est rassurant :) )
 
Recompilez votre programme en débug et valgrind vous indiquera pour chaque erreur le numéro de la ligne correspondante, et vous pourrez corriger très rapidement.
 
Bonne continuation !

n°2182002
alexanonym​ous
Posté le 23-03-2013 à 12:57:59  profilanswer
 

Hum, d'accord. Effectivement, je crois qu'on avance. Deux petits problèmes : Premièrement, je ne connais pas bien Valgrind. Quand vous dites "Recompilez votre programme en débug", ça signifie rajouter l'option -g ? En tout cas, après avoir fait ça, j'obtiens ceci :
 
==2059== Invalid read of size 4
==2059==    at 0x804883F: FC (test.c:126)
==2059==    by 0x8048960: main (test.c:155)
==2059==  Address 0xbefadff0 is not stack'd, malloc'd or (recently) free'd
 
Puis un peu plus loin...
 
==2059== Conditional jump or move depends on uninitialised value(s)
==2059==    at 0x8048881: FC (test.c:132)
==2059==    by 0x8048960: main (test.c:155)
 
Donc si j'ai bien compris, mon affectation de ma matrice tmp (ligne 126) ne s'est pas faite correctement, ce qui explique le "Conditional jump or move depends on uninitialised value(s)" ligne 132. Ce qui explique également que mon résultat soit faux. Ca se tient. Seulement, pourquoi cette affectation s'est mal déroulée ? Je ne comprends pas très bien le message d'erreur. L'affectation de tmp a été faite sur matrice_pointeurs, qui elle-même a été faite dans la fonction couleur_graphe, à partir de la ligne 94...
 
Deuxième problème, et je crois que c'est ce qui me rend fou, pourquoi diable un printf change-t-il le résultat ? J'ai bien compris que mes erreurs apparaissent aussi quand je l'enlève, même si j'ai le bon résultat. Mais comment ça se fait ? Le printf aurait changé des choses dans les pointeurs, les affectations ?

n°2182013
Farian
Posté le 23-03-2013 à 14:24:03  profilanswer
 

Bonjour ! L'erreur indique simplement que l'une des valeurs "d'entrée" de l'affectation ligne 126 n'est pas initiailisée.
 
Le mieux, pour savoir laquelle est de remplacer :  

Code :
  1. tmp.mat[c1][c2]=matrice_pointeurs[i][k]->mat[c1][c2];


par

Code :
  1. printf("%d %d %d %d %X \n", i, k, matrice_pointeurs[i][k]);
  2. printf("%d %d %d %d %d \n", matrice_pointeurs[i][k]->mat[c1][c2]);
  3. tmp.mat[c1][c2]=matrice_pointeurs[i][k]->mat[c1][c2];


 
qui vous donnera toutes les informations, et surtout vous indiquera laquelle des deux valeurs n'est pas initialisée. Une fois celle-ci identifiée, remontez la chaîne !
 
Bonne continuation !


Message édité par Farian le 23-03-2013 à 14:58:45
n°2182015
gilou
Modérateur
Modzilla
Posté le 23-03-2013 à 14:27:42  profilanswer
 

Bon, je crois que j'ai compris:
tmp.mat[c1][c2]=matrice_pointeurs[i][k]->mat[c1][c2];
cette ligne pose problème par la suite, ce qui veut dire qu'il y a du pointeur nul ou invalide qui traine...
ou matrice_pointeurs[i][k] est il mis à autre chose que NULL?
Dans couleur_graphe, ou on fait:
matrice_pointeurs[0][1]=&contraintes[0];
etc
Quelle est la durée de vie de contraintes?
contraintes est déclaré comme  
matrice contraintes[M];
dans couleur_graphe, donc sa durée de vie est limitée à celle de couleur_graphe
et donc comme dans FC, on n'est plus dans couleur_graphe, les zones mémoires utilisées pour contraintes peuvent donc être réutilisées...
 
A+,


Message édité par gilou le 23-03-2013 à 14:28:00

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2182017
Farian
Posté le 23-03-2013 à 14:57:50  profilanswer
 

En effet, vos matrices "contraintes" sont déclarées dans une variable locale, dont vous stockez les adresses des éléments dans matrice_pointeurs puis, à la fin de la fonction, la mémoire est désallouée.  
 
Le cycle de vie de la matrice "contraintes" n'est pas suffisant, déclarez-la elle aussi en variable dans le "main" et passez là à la fonction "couleur_graphes" et tout ira mieux ! :)
 
Bien vu, gilou !


Message édité par Farian le 23-03-2013 à 14:58:25
n°2182074
alexanonym​ous
Posté le 23-03-2013 à 22:17:15  profilanswer
 

Merci de votre aide, vous êtes des génies ! Donc, permettez-moi de résumer pour être sûr d'avoir bien compris :
Ma matrice matrice_pointeurs, qui comme son nom l'indique est une matrice de pointeurs, a pour éléments soit des pointeurs pointant sur NULL, soit des pointeurs pointant sur une autre matrice, mais une matrice d'entiers. Ce sont les fameuses "contraintes". contraintes est défini localement dans couleur_graphe, donc à cet instant, matrice_pointeurs pointe où il faut, comme il faut. Mais à la fin de la procédure, matrice_pointeurs pointe sur des trucs potentiellement désalloués, puisqu'ils étaient locaux.
C'est là que je suis pas sûr : en fait, si je touche à pas grand chose, tout se passe bien ? Mais si je fais un printf, celui-ci nécessite un tout petit peu de mémoire et mon OS peut décider d'allouer l'emplacement qui était celui des contraintes. Donc matrice_pointeurs va pointer au bon endroit, mais sur des valeurs qui ont pu changer. C'est pourquoi mon résultat final s'en retrouve erroné ?
 
Bref, j'ai bien compris ?
 
Bon sinon, en modifiant mon code le plus simplement possible, valgrind me donne :
 
==1944== HEAP SUMMARY:
==1944==     in use at exit: 0 bytes in 0 blocks
==1944==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==1944==  
==1944== All heap blocks were freed -- no leaks are possible
==1944==  
==1944== For counts of detected and suppressed errors, rerun with: -v
==1944== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
 
Ca signifie plus d'erreur, n'est-ce pas ?
 
Dernière question ? Dois-je modifier le sujet du topic en rajoutant un tag résolu, ou quelque chose comme ça ? :)
 
En tout cas, merci encore de votre aide !

n°2182079
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 23-03-2013 à 23:53:44  profilanswer
 

alexanonymous a écrit :

Bon sinon, en modifiant mon code le plus simplement possible, valgrind me donne :
 
==1944== HEAP SUMMARY:
==1944==     in use at exit: 0 bytes in 0 blocks
==1944==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==1944==  
==1944== All heap blocks were freed -- no leaks are possible
==1944==  
==1944== For counts of detected and suppressed errors, rerun with: -v
==1944== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
 
Ca signifie plus d'erreur, n'est-ce pas ?


 
Ça signifie qu'avec les paramètres que tu as mis dans ton programme il n'y a effectivement plus de fuites mémoire ou d'accès à des valeurs non initialisées, ce qui était ton problème à la base :jap:


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010

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

  Printf qui change le résultat d'un programme ??

 

Sujets relatifs
Programme débutantRe-programmer un logiciel ?
Pb pour fermer programme avec touche clavier. (VB)[C/C++]Programme cube led, besoin d'aide pour comprendre
Aide Réalisation d'un programmeChoix d'un langage pour un programme précis
[C] Petit programmeaide pour programme sous codeblocks
[VBA] fonction paramétré renvoyant le résultat d'une requête ACCESSProblème programme C
Plus de sujets relatifs à : Printf qui change le résultat d'un programme ??


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