IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Variable qui change de valeur toute seul :(


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Points : 120
    Points
    120
    Par défaut Variable qui change de valeur toute seul :(
    Bonjour,
    Alors voila j'ai un gros probleme.
    Je travail sur un mini-Projet en C. Je dois faire une calculatrice.
    Bon j'ai termine tout le code de la calculatrice. Et la je travail sur le dessin d'une courbe de dessin. Pour cela j'utilise 3 variable Max,Min,Densite.
    Pour le moment je n'ai ecrit aucune fonction qui modifie ces valeurs.
    Pourtant la valeur de Max change. J'ai un peu trace le code et il semblerait que la modification se fait au niveau de cette fonction :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    int ResultatFonction(char * Op,DPoint **  Liste ,double Max,double Min,int n)
    	{
    	double x=0;
    	double r=0;
    	double pas = 1;//(Max-Min)/n;
    	int err=0; 
    	int c=0; //Compte le nombre de points valide
    	Vider(Liste);
    	x=Min;
    	while(x<=Max)
    		{
    		Val_Constantes[4]=x;
    		err=CalculerOperation(Op,&r);
    		if (err == ERR_SUCCES)
    			{
    			Push(Liste,x,r);
    			c++;
    			}
    		x+=pas;
    		}
    	if (c==0) return ERR_NEPEUTDESSINER; // Si nous n'avons aucun point valide alors on la fonction ne peut etre dessiner avec ses parametres
    	return ERR_SUCCES;
    	}
    Liste : c'est une liste chainee. j'ai utilise un code que j'ai trouver sur Devellopez.com
    CalculerOperation : Calcul une formule mathematique du style 5+10log(4)...
    Val_Constantes[4]=x; : La constante "x" est predefini et remplacé dans la CalculerOperation par Val_Constantes[4]. donc si Val_Constantes[4]=4 et qu'on a 5+x. CalculerOperation renvoi 9.
    En fait Max prend la valeur de r dans la derniere iteration. (Si je prend comme fonction f(x)=0 Max = 0, f(x)=2x Max = 2*Max...
    Lors de l'appel de la fonction si je met
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ResultatFonction(Op,&Liste ,Min,Max,Densite)
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ResultatFonction(Op,&Liste ,Max,Min,Densite)
    Le probleme disparait (enfin peut etre qu'une autre variable est touche).

    Au debut de mon programme je define les trois variables.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    double Max=10;
    double Min=-10;
    double Densite=50;
    Lorsque j'interverti Densite et Max :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    double Densite=50;
    double Max=10;
    double Min=-10;
    c'est Densite qui change.
    Alors juste pour tester j'ai cree un variable qui n'est utilise null part et je l'initialise à 100
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    double Salut=100;
    double Densite=50;
    double Max=10;
    double Min=-10;
    Et maintenant c'est Salut qui change.

    Si je declare ces variables comme constante, plus de probleme. Seulement je dois les modifer. Au pire je pense les declarer const et ajouter des variable zoom et incDensite. et faire un truc du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ResultatFonction(Op,&Liste ,Max*zoom,Min*zoom,Densite*IncDensite)
    Mais franchement c'est moche. En plus je devrais l'expliquer a mes profs alors.

    Je pense que ca doit etre un probleme de chevauchement de variables en memoire mais je ne sais pas trop comment y remedier.
    Ps: Mon projet est en C, si vous pouviez me donner que des solutions C et non C++. (Quoique meme en compilant en tant que c++ le probleme reste le meme)

    Je travail sous VisualC++(Avec Visual Studio 2005) et je n'utilise que les bibliotheques AINSI et WIN32(Pour l'interface).
    Merci pour votre aide.

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par lcfseth Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    		Val_Constantes[4]=x;
    Comment est défini Val_Constantes ? Les globales, çaÿ mal...
    Pas de Wi-Fi à la maison : CPL

  3. #3
    Membre régulier
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Points : 120
    Points
    120
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Comment est défini Val_Constantes ? Les globales, çaÿ mal...
    char * Constantes[] = {"pi","e","c","g","x","a","b","c","d","e","m","m1","m2","m3","m4"};//Contient les chaines representant les constantes
    double Val_Constantes[] = {CPI,CE,299792458,6.6742e-11,0,0,0,0,0,0,0};

    Je suis oblige de les declarer en global car ils sont uilise au cours de 3 fonctions successive. Mais j'ai deja teste le code en mode console et il fonctionne parfaitement. Ce n'est que lorsque j'ai voulu rajoute la partie dessin de courbe(donc passage à du win32) qu'est apparu le probleme.

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par lcfseth Voir le message
    char * Constantes[] = {"pi","e","c","g","x","a","b","c","d","e","m","m1","m2","m3","m4"};//Contient les chaines representant les constantes
    double Val_Constantes[] = {CPI,CE,299792458,6.6742e-11,0,0,0,0,0,0,0};
    Et tu modifies une constante ?
    A moins que... tu mélanges dans le même tableau, des valeurs fixes et des variables ? C'est plutôt bizarre comme conception.

    Et pour les valeurs constantes, qu'est-ce qui t'empêche d'utiliser des macros (#define) ? Je ne vois pas à quoi sert le tableau de constantes, à part pour compliquer le code inutilement...
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Membre régulier
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Points : 120
    Points
    120
    Par défaut
    Si je n'utilise pas de #define c'est parceque ce ne sont pas des constantes que j'utilise dans mon programme. En realite lorsque l'utilisateur entre une operation du style "5e+4pi" Une premiere fonction utilise le premier tableau pour reformuler l'operation de facon plus conventionel en "5*e+4*pi"
    et la fonction Calcul va utiliser le second tableau pour remplacer "e" et "pi" par leur valeur.
    Utiliser un tableau me permet de m'affranchir des long switch et me permet de rajouter de nouvelles constantes sans modifier le code source.
    Il me suffit de rajouter 2 valeur et de redefinir la valeur "NombreDeConstantes". (qui est une constante definie en utilisant #define)

    Pour le nom, au depart je voulais simplement utiliser des constantes mais je me suis apercu que je pouvais introduire la notion de variable, En definissant une constante (au sens mathematique et non algorithmique) "x" et on modifiant sa valeur avant chaque appel. La fonction Calcul la considere a chaque fois comme constante. Je peux ainsi utilise une meme operation ("5x" par exemple) pour calculer plusieurs valeurs que je
    pourais utilisé pour dessiner la courbe de la fonction f(x)=5*x.


    Je sais qu'il y a mieux, mais je prefere faire long et pas optimise mais avoir un principe que je pourrais expliquer simplement ( certain de mes profs sont assez lents ;( )

  6. #6
    Membre averti Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Points : 390
    Points
    390
    Par défaut
    Bonjour,

    Votre problème semble effectivement étrange, et il est difficile de rentrer dedans. Vous avez fait plusieurs tests, admettez que vous pouvez peut-être en avoir fait un un peu rapidement dans l'énervement. Deux suggestions:
    - Min et Max sont des noms dangereux, ils peuvent éventuellement avoir été définis "ailleurs". Rendez-leur leurs chances d'être uniques, par exemple en les renommant Min_Calc_Canvas et Max_Calc_Canvas.
    - Faîtes souvent des clean builds, et en particulier après un refactoring comme évoqué ci-dessus. Et surtout quand vous introduisez win32. Là, vous pouvez carrément créer un autre projet, et copier/coller vos sources.

    Si la variable change de façon reproductible, n'hésitez pas à utiliser le débogueur pour la surveiller. Ni à faire des recherches sur son nom sur l'ensemble du projet.

    Good luck...

  7. #7
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Vraiment bizarre ton probleme... Meme si je comprend pas grand chose à ce qu'est censé faire ton programme (je suis loin d'être un pro...), il est clair que quand tu passes Max en parametres, il ne peut théoriquement pas être modifié, puisque c'est un passage par valeur. Et ce que je ne comprend pas, c'est pourquoi tu passes Max en parametre, s'il existe déja en global au dessus.
    Et de plus quand tu dis que la variable est modifiée au niveau de cette fonction, est ce que cela signifie bien que, si tu fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    printf("%f\n",Max);
    ResultatFonction(Op,&Liste ,Min,Max,Densite)
    printf("%f\n",Max);
    Cela n'imprime pas la même valeur??
    Et sinon ce que je ferais à ta place, c'est d'imprimer la valeur de la variable qui se modifie toute seule un peu partout dans ta fonction, histoire de voir à quel moment elle change vraiment (enfin peut être que tu l'as déja fait...).

  8. #8
    Membre régulier
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Points : 120
    Points
    120
    Par défaut
    Merci Pierre Maurette.
    J'ai fait ce que vous m'avez conseille mais rien n'a change. Pour ce qui est de renommer Max et Min (je l'ai fait) mais Comme je l'ai explique : j'ai declare une variable "salut" que je n'utilise pas dans mon programme et qui me semble n'avoir aucune raison d'etre definie ailleurs. Le probleme perciste.

    Et pour ce qui est du debug, j'arrive pas à mettre des beakpoints sur mon programme. En fait je les mets mais ca ne marche pas. Ayant l'habitude de travailler sur DevC++ je ne suis pas encore tres a l'aise avec toutes les options de VC++. J'utilise une edit box pour afficher les valeurs que je souhaite surveiller. Je vais mettre le code de la fonction au cas ou :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
     
    int AjouterTexte(HWND hwnd, char * texte,long Color, int Bold , int Italic)
    	{
     
    	CHARFORMATA format;
    	format.cbSize = sizeof(CHARFORMAT);
    	format.dwMask = CFM_BOLD |CFM_ITALIC | CFM_COLOR 	 ;
    	format.crTextColor = Color;
    	format.dwEffects = 0;
    	if (Bold) format.dwEffects  |= CFE_BOLD	;
    	if (Italic) format.dwEffects  |= CFE_ITALIC	;
    	SendMessageA(hwnd,EM_SETCHARFORMAT,SCF_SELECTION,(LPARAM)&format);
    	return SendMessageA(hwnd,EM_REPLACESEL,0,(LPARAM)texte);
     
    	}
     
    int AjouterNombre(HWND hwnd,double X)
    	{
    	char * buffer = (char *) malloc(255);
    	sprintf_s(buffer,255,"%G", X );
    	return AjouterTexte(hwnd,buffer,NUMCOLOR,0,0);
    	free (buffer);
    	}
    ps: Si je suis ici c'est que j'ai deja admis le fait que je pouvais avoir tout fais de travers

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lcfseth Voir le message
    Bonjour,
    Alors voila j'ai un gros probleme.
    Je travail sur un mini-Projet en C. Je dois faire une calculatrice.
    Bon j'ai termine tout le code de la calculatrice. Et la je travail sur le dessin d'une courbe de dessin. Pour cela j'utilise 3 variable Max,Min,Densite.
    Pour le moment je n'ai ecrit aucune fonction qui modifie ces valeurs.
    Pourtant la valeur de Max change. J'ai un peu trace le code et il semblerait que la modification se fait au niveau de cette fonction :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    int ResultatFonction(char * Op,DPoint **  Liste ,double Max,double Min,int n)
    	{
    	double x=0;
    	double r=0;
    	double pas = 1;//(Max-Min)/n;
    	int err=0; 
    	int c=0; //Compte le nombre de points valide
    	Vider(Liste);
    	x=Min;
    	while(x<=Max)
    		{
    		Val_Constantes[4]=x;
    		err=CalculerOperation(Op,&r);
    		if (err == ERR_SUCCES)
    			{
    			Push(Liste,x,r);
    			c++;
    			}
    		x+=pas;
    		}
    	if (c==0) return ERR_NEPEUTDESSINER; // Si nous n'avons aucun point valide alors on la fonction ne peut etre dessiner avec ses parametres
    	return ERR_SUCCES;
    	}
    En fait Max prend la valeur de r dans la derniere iteration. (Si je prend comme fonction f(x)=0 Max = 0, f(x)=2x Max = 2*Max...
    Lors de l'appel de la fonction si je met
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ResultatFonction(Op,&Liste ,Min,Max,Densite)
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ResultatFonction(Op,&Liste ,Max,Min,Densite)
    Le probleme disparait (enfin peut etre qu'une autre variable est touche).

    Au debut de mon programme je define les trois variables.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    double Max=10;
    double Min=-10;
    double Densite=50;
    Lorsque j'interverti Densite et Max :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    double Densite=50;
    double Max=10;
    double Min=-10;
    c'est Densite qui change.
    Alors juste pour tester j'ai cree un variable qui n'est utilise null part et je l'initialise à 100
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    double Salut=100;
    double Densite=50;
    double Max=10;
    double Min=-10;
    Et maintenant c'est Salut qui change.

    Si je declare ces variables comme constante, plus de probleme. Seulement je dois les modifer. Au pire je pense les declarer const et ajouter des variable zoom et incDensite. et faire un truc du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ResultatFonction(Op,&Liste ,Max*zoom,Min*zoom,Densite*IncDensite)
    Mais franchement c'est moche. En plus je devrais l'expliquer a mes profs alors.

    Je pense que ca doit etre un probleme de chevauchement de variables en memoire mais je ne sais pas trop comment y remedier.
    Ps: Mon projet est en C, si vous pouviez me donner que des solutions C et non C++. (Quoique meme en compilant en tant que c++ le probleme reste le meme)

    Je travail sous VisualC++(Avec Visual Studio 2005) et je n'utilise que les bibliotheques AINSI et WIN32(Pour l'interface).
    Merci pour votre aide.
    Tout ceci est une illustration parfaite d'un comportement indéterminé.
    A un moment donné, tu vas écrire dans un pointeur ou un tableau plus que ce qu'il peut recevoir et donc ce qui déborde va écraser des emplacements utilisés par d'autres variables. T'es dans la pire des situations. Faut que tu retrouves un bug qui peut dater d'il y a 6 mois et qui est maintenant noyé dans le reste.

    Déjà les remarques de Emmanuel sont utiles. Les globales c'est le mal. Tes variables sont utilisées dans 3 fonctions ben les 3 fonctions reçoivent ces variables en paramètre. Cela rend tes fonctions trop lourdes (trop de paramètres) alors tu regroupes les variables allant ensemble dans une structure et tu passes l'adresse de ta structure à tes fonctions (avec l'adresse les fonctions peuvent retrouver les variables associées).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Membre régulier
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Points : 120
    Points
    120
    Par défaut
    Desole Climoo mais nos deux reponse se sont faites simultanement.
    Bon alors tu a raison pour le passage des variables.
    En realite j'ai separe tout ce qui mathematique de ce qui a attrait au graphique. donc la fonction ResultatFonction() se trouve dans un autre fichier que WinMain() où sont declarer Max et Min.
    Et exactement, je n'utilise pas de printf puisque je suis sous win32 mais c'est exactement ce qui se passe.
    Pour isoler le probleme j'ai supprimer tout le code de dessin qui est le seul endroit a part l'appel de la fonction ResultatFonction() ou mes deux variables sont utilises.
    La seul solution qui me vient à l'esprit c'est d'utiliser la variable "salut" comme leurre. La laisser changer de valeur si elle le souhaite puisque je ne m'en sers pas. Mais ca m'inquiete pour la stabilite de mon programme (je voudrais pas qu'il crash pendant ma demo).

  11. #11
    Membre régulier
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Points : 120
    Points
    120
    Par défaut
    Vous etes drolement actifs sur ce forum. bravo
    Bon je vais voir Sve@r. Je me doutais bien que ce serais un truc dans ce genre là.
    je vais tenter de trouver la faille. Ce que je ne comprend pas c'est pourquoi ca prend la valeur de r (la variable ou est stocke le resultat du calcul) ? est ce que ca peut m'aider à trouver la faille ?
    Et est ce qu'il y a moyen de mettre un breakpoint sur toute modification de la variable max autre que de passer par un debugger externe(OllyDbg dans mon cas). Pour voir a quel moment elle est modifie.
    Autre question, c'est un peu hors sujet mais ca concerne les variable globales.
    Pour dessiner dans ma fenetre je dois recuperer le message WM_PAINT et dessiner dedans. Je suis à priori oblige de recourir a des variables globales pour passer mes parametres à ma fonction de dessin. non?

  12. #12
    Membre régulier
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Points : 120
    Points
    120
    Par défaut
    Voila j'ai trouve la solution : Effectivement j'avais l'une de mes competeurs qui depassait. Je n'ai pas encore trouve ou l'erreur se produit exactement mais en decrementant ma variable "Nombre_DeConstantes" plus de problemes.
    Merci beaucoup. Je vais mettre le flage "resolu".

  13. #13
    Membre régulier
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Points : 120
    Points
    120
    Par défaut
    Voila c'est reelement resolus. En fait le tableau des noms de constantes contenait 15 valeur alors que celui des valeurs des constantes lui n'en contenais que 12. D'ou l'erreur. Merci beaucoup. Non seulement j'ai plus d'erreur mais en plus je vais pouvoir rearanger mon code pour qu'il soit un peu plus stable grace à vos conseils

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Variable qui s'initialise à 0 toute seule
    Par algerino77 dans le forum C++Builder
    Réponses: 9
    Dernier message: 21/05/2014, 12h48
  2. Variable qui se remet à 0 TOUTE SEULE
    Par wilfryjules dans le forum C++
    Réponses: 17
    Dernier message: 12/02/2014, 00h34
  3. Variable qui change de valeur "toute seule"
    Par GDMINFO dans le forum C++
    Réponses: 9
    Dernier message: 14/10/2010, 18h12
  4. Variable qui change de valeur à chaque appel de fonction
    Par bpascal123 dans le forum Débuter
    Réponses: 5
    Dernier message: 12/03/2010, 11h47
  5. Form qui change de position toute seul dans un mdiContainer
    Par obitskater dans le forum Windows Forms
    Réponses: 4
    Dernier message: 30/03/2009, 13h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo