Résolu : variable modifiée par l'affectation d'une autre variable

Résolu : variable modifiée par l'affectation d'une autre variable - C - Programmation

Marsh Posté le 22-05-2010 à 19:13:11    

Bonjour (ou bonsoir) :hello:
 
J'ai un problème qui me casse la tête et que je vais essayer de vous décrire le plus simplement possible :
 
J'ai une variable A qui vaut 1792,
j'appelle une fonction qui ne prend pas A en argument,
et juste après, si j'affiche A, la valeur a changé, la variable vaut 3.
 
Donc en gros, si mon code est (les noms des variables et fonctions sont fictifs car pas importants) :
 

Code :
  1. printf("%d\n", A);
  2. fonction1(&B, &C, &D);
  3. printf("%d\n", A);


ça donne :
 
1792
3
 
Pour comprendre ce qui se passe, j'ai passé l'addresse de A en argument dans fonction1  
j'ai remarqué en faisant des printf partout que le changement de valeur se faisait au niveau d'une ligne :
 

Code :
  1. cache_SA[index].tag[w] = new_tag;


 
avec index = 4, w = 3 et new_tag = 3
 
cache est de type struct cacheline_SA avec :
 

Code :
  1. struct cacheline_SA
  2. {
  3.    unsigned int tag[32];
  4.    unsigned long long value[32];
  5.    unsigned char dirty[32];
  6.    unsigned char active[32];
  7.    char age[32];
  8. };


On dirait que la valeur (3) n'a pas été enregistrée là où il faut dans la mémoire ( surprenant! ) et a "empiété" sur ma variable A.
 
Pour avoir à peu près une idée ( mais au final ça me dit pas grand chose), j'ai affiché les addresses des variables en question :
 
A est à l'addresse 0xbfeff3ec
cache_SA est à l'addresse 0xbfefec60
cache_SA[4].tag est à l'addresse 0xbfeff3e0
 
la taille de ma structure ( d'après sizeof ) est de 480B et 0xbfefec60 + 0x1e0 (480) = 0xbfefee40 < 0xbfeff3ec (addresse de A)
donc ça devrait pas poser de problème, cela dit je me trompe peut être car je suis pas sûr de mon calcul...
 
Vous auriez une idée pour expliquer ce phénomène et corriger mon code pour ne pas avoir ce problème ?
Il y a une solution bricolage qui serait de sauvegarder la valeur de A à une autre adresse et puis la ressortir après l'execution de la fonction1, mais bon... c'est vraiment pas propre comme solution...
 
Merci!
 
 :jap:

Message cité 1 fois
Message édité par ohcto le 22-05-2010 à 22:05:36
Reply

Marsh Posté le 22-05-2010 à 19:13:11   

Reply

Marsh Posté le 22-05-2010 à 21:36:13    

ohcto a écrit :

Bonjour (ou bonsoir) :hello:
 
J'ai un problème qui me casse la tête et que je vais essayer de vous décrire le plus simplement possible :
 
J'ai une variable A qui vaut 1792,
j'appelle une fonction qui ne prend pas A en argument,
et juste après, si j'affiche A, la valeur a changé, la variable vaut 3.
 
Donc en gros, si mon code est (les noms des variables et fonctions sont fictifs car pas importants) :
 

Code :
  1. printf("%d\n", A);
  2. fonction1(&B, &C, &D);
  3. printf("%d\n", A);


ça donne :
 
1792
3


C'est quoi les types de B, C et D (je présume que A est de type int) ?
 

ohcto a écrit :

Pour comprendre ce qui se passe, j'ai passé l'addresse de A en argument dans fonction1  
j'ai remarqué en faisant des printf partout que le changement de valeur se faisait au niveau d'une ligne :
 

Code :
  1. cache_SA[index].tag[w] = new_tag;


 
avec index = 4, w = 3 et new_tag = 3
 
cache est de type struct cacheline_SA avec :
 

Code :
  1. struct cacheline_SA
  2. {
  3.    unsigned int tag[32];
  4.    unsigned long long value[32];
  5.    unsigned char dirty[32];
  6.    unsigned char active[32];
  7.    char age[32];
  8. };


On dirait que la valeur (3) n'a pas été enregistrée là où il faut dans la mémoire ( surprenant! ) et a "empiété" sur ma variable A.


J'espère que le tableau cache_SA est de taille suffisante (au-moins 5 struct cacheline_SA) !!!
 

ohcto a écrit :

Pour avoir à peu près une idée ( mais au final ça me dit pas grand chose), j'ai affiché les addresses des variables en question :
 
A est à l'addresse 0xbfeff3ec
cache_SA[4].tag est à l'addresse 0xbfeff3e0
 
 
la taille de ma structure ( d'après sizeof ) est de 480B et 0xbfefec60 + 0x1e0 (480) = 0xbfefee40 < 0xbfeff3ec (addresse de A)
donc ça devrait pas poser de problème, cela dit je me trompe peut être car je suis pas sûr de mon calcul...


Ben oui. Tu n'as pas "une" structure mais un tableau de "n" structures. Faut faire 0xbfefec60 + n * 0x1e0 !!!
Et si je fais 0xbfefec60 + 3 * 0x1e0 j'arrive pile poil sur 0xbfeff3e0 qui est l'adresse de cache_SA[4].tag et qui est aussi à seulement 12 octets de A !!! En dehors de cette variable A, je me demande bien quelles autres malheureuses variables vont se faire écraser par les zones value, dirty et active situées juste après tag... [:spamafote]
 

ohcto a écrit :

Vous auriez une idée pour expliquer ce phénomène et corriger mon code pour ne pas avoir ce problème ?
Il y a une solution bricolage qui serait de sauvegarder la valeur de A à une autre adresse et puis la ressortir après l'execution de la fonction1, mais bon... c'est vraiment pas propre comme solution...


Oui, pas mauvaise idée. Et si t'es sous système Unix/Linux, tu pourras même rajouter un 2>/dev/null après le lancement de ton exécutable comme ça tu ne seras pas embêté par les messages d'erreurs s'il y en a...
Quand il y a un soucis vaut mieux trouver sa cause pour le faire disparaitre plutôt que de l'esquiver.
De toute façon tu décris ici un cas typique de comportement indéterminé. Style t'as alloué 10 et tu remplis 11. Déjà mis à part mes questions précédentes, si on pouvait avoir le code de "fonction" ce serait un plus mais à mon avis l'idée du tableau [4] est une bonne piste...

Message cité 2 fois
Message édité par Sve@r le 22-05-2010 à 21:54:44

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

Marsh Posté le 22-05-2010 à 21:38:10    

Donc, en deux mots, malloc foireux.


---------------
Any sufficiently complex bug is indistinguishable from magic.
Reply

Marsh Posté le 22-05-2010 à 21:54:26    

Sve@r a écrit :


C'est quoi les types de B, C et D (je présume que A est de type int) ?
 


 
B, C et D c'était pour simplifier, la fonction en elle même c'est ça :
 

Code :
  1. void pram_read_SA( sector_lst  *memory,
  2.                       mt_lst   *mapping_table,
  3.                       unsigned int  *last_ic,
  4.                       // cache
  5.                       struct cacheline_SA *cache,
  6.                       struct cache_spec cache_spec_SA,
  7.                       unsigned char  *hit,
  8.                       // input  
  9.                       unsigned int  trace_addr,
  10.                       unsigned char  trace_size,
  11.                       // output
  12.                       unsigned char   *n_read,
  13.                       unsigned char  *n_read_OV,
  14.                       unsigned char  *n_set_OV,
  15.                       unsigned char  *n_reset_OV,
  16.                       unsigned char  *read_acc,
  17.                       unsigned char  *write_acc,
  18.                       // parameter
  19.                       unsigned char  disp_on,
  20.                       FILE   *fpW,
  21.                       // debug
  22.                       unsigned int  *var )


 
et voici son appel :
 

Code :
  1. pram_read_SA(&mem_SAA,
  2.              &mt_SAA, &last_ic_SAA,
  3.              cache_SAA, cache_spec_SAA, &hit_SAA,
  4.              trace_addr, trace_size,
  5.              &n_read[3],
  6.              &n_read_OV[3], &n_set_OV[3], &n_reset_OV[3],
  7.              &read_acc[3], &write_acc[3],
  8.              disp_on & SHOW_SAA, fpW,
  9.              &last_ic_FNW );


 

Sve@r a écrit :


J'espère que le tableau cache_SA est de taille suffisante (au-moins 5 struct cacheline_SA) !!!
 


 
comment ça ?
 
le tableau cache_SA est déclaré ainsi :
 

Code :
  1. struct cacheline_SA  cache_SAB[4];


 
.................................. :heink: je crois que je viens à l'instant de trouver mon erreur (en rouge) !!  [:arn0]  
 

Sve@r a écrit :


T'as vu que ton cache_SA[4].tag est à 12 octets de A ??? Je me demande où vont aller value, dirty et active... [:clooney46]  
 
je crois que j'aurais du mettre 512 et j'ai mis 4  [:arn0]  
 


 

Sve@r a écrit :


De toute façon tu décris ici un cas typique de comportement indéterminé. Style t'as alloué 10 et tu remplis 11. Déjà mis à part mes questions précédentes, si on pouvait avoir le code de "fonction" ce serait un plus.  
J'espère aussi que A n'est pas une variable globale (ni aucune autre d'ailleurs)...


 
vi, ton diagnostic était le bon :jap:
non, A n'est bien sûr pas globale...
 

_iOn_ a écrit :

Donc, en deux mots, malloc foireux.


 
j'utilise pas malloc :kaola:


Message édité par ohcto le 22-05-2010 à 21:58:11
Reply

Marsh Posté le 22-05-2010 à 22:01:26    

Sve@r a écrit :


Ben oui. Tu n'as pas "une" structure mais un tableau de "n" structures. Faut faire 0xbfefec60 + n * 0x1e0 !!!
Et si je fais 0xbfefec60 + 3 * 0x1e0 j'arrive pile poil sur 0xbfeff3e0 qui est l'adresse de cache_SA[4].tag et qui est aussi à seulement 12 octets de A !!! En dehors de cette variable A, je me demande bien quelles autres malheureuses variables vont se faire écraser par les zones value, dirty et active situées juste après tag... [:spamafote]
 


 
merci tu m'as aidé à trouver mon problème :jap:
dédicément, j'ai passé des heures à vérifier re-vérifier en croyant n'avoir fait aucune erreur et finalement c'était juste là, devant mes yeux  [:eric le looser]


Message édité par ohcto le 22-05-2010 à 22:01:52
Reply

Marsh Posté le 22-05-2010 à 22:03:06    

[:alain_wakbar]
Bon ben voilà quoi. Tu marques "RESOLU" dans le titre, ensuite tu cours vite te cacher loin de la communauté scientifique qui te contemple et qui te juge et demain tout sera oublié  :bounce:  :bounce:  :bounce:

Message cité 1 fois
Message édité par Sve@r le 22-05-2010 à 22:03:49

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

Marsh Posté le 22-05-2010 à 22:05:06    

Sve@r a écrit :

[:alain_wakbar]
Bon ben voilà quoi. Tu marques "RESOLU" dans le titre, ensuite tu cours vite te cacher loin de la communauté scientifique qui te contemple et qui te juge et demain tout sera oublié  :bounce:  :bounce:  :bounce:


 
c'est bon je suis déjà caché [:ddr555]


Message édité par ohcto le 22-05-2010 à 22:05:59
Reply

Sujets relatifs:

Leave a Replay

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