Référence en 64 bits

Référence en 64 bits - C++ - Programmation

Marsh Posté le 01-01-2011 à 03:05:13    

Bonjour je commence par un message d'erreur :
 

Code :
  1. [noeud11:14001] *** Process received signal ***
  2. [noeud11:14001] Signal: Segmentation fault (11)
  3. [noeud11:14001] Signal code: Address not mapped (1)
  4. [noeud11:14001] Failing at address: 0x1809
  5. [noeud11:14001] [ 0] /lib64/libpthread.so.0 [0x369b60eb10]
  6. [noeud11:14001] [ 1] /usr/lib64/libstdc++.so.6(_ZNSs6assignERKSs+0x2e) [0x36a0e9c9de]
  7. [noeud11:14001] [ 2] ./hier(_ZN14OmegaLongChain9SavePointEv+0x7d2) [0x4c0ae0]
  8. [noeud11:14001] [ 3] ./hier(_ZN14OmegaLongChain5StartEv+0x3e4) [0x4cedfe]
  9. [noeud11:14001] [ 4] ./hier(main+0x717) [0x47a2bf]
  10. [noeud11:14001] [ 5] /lib64/libc.so.6(__libc_start_main+0xf4) [0x369aa1d994]
  11. [noeud11:14001] [ 6] ./hier(__gxx_personality_v0+0x331) [0x478409]
  12. [noeud11:14001] *** End of error message ***


 
Vous pouvez remarquer qu'il y a des pointeurs du type 0x47a2bf et d'autres du type 0x36a0e9c9de. C'est ca qui pose problème. Le code est enorme compliqué, en C++, il inclue des librairies C car j'utilise MPI pour paralléliser et a un moment dans mon code, pas toujours au meme selon le nombre de processus qui j'inclu ( bizarre ... ) Les pointeurs doublent de taille.
Un exemple ou j'ai locallisé l'erreur :
 

Code :
  1. void* s;
  2.   cerr <<sizeof(s)<<' '<< s << '\n';
  3.   is->Sub(s);
  4.   cerr <<sizeof(s)<<' '<< s << '\n';


 
avec is->Sub(s) qui appelle cette fonction :
 

Code :
  1. template<class T>
  2. void Sub(T& value)  {
  3.  char* temp = new char[ sizeof(T)];
  4.  for (unsigned int i=0; i<sizeof(T); i++)    {
  5.   temp[i] = SubChar();
  6.  }
  7.  value = ((T*) temp)[0];
  8.  delete[] temp;
  9. }


 
La sortie est :
 

Code :
  1. 8 0x4c34ab
  2. 8 0x6c2ae4800000000


 
N'importe quelle idée est la bienvenue ...
Merci !
 
 
 
 
 

Reply

Marsh Posté le 01-01-2011 à 03:05:13   

Reply

Marsh Posté le 01-01-2011 à 09:42:05    

Salut :)
 
 
Ligne 2 , s n'est pas initialisé, il vaut donc à peu près n'importe quoi, c'est à dire 0x4c34ab dans ton cas. C'est bien une valeur 64 bits, c'est en fait  0x00000000004c34ab.
 
 
Ta fonction Sub (ligne 3) modifie la valeur de s , il est donc normal que son contenu soit modifié (ligne 7 de la fonction Sub ). Par contre, je ne vois pas ce que tu cherches à faire sur cette ligne.

Reply

Marsh Posté le 01-01-2011 à 23:19:07    

Salut, meci de ta réponse !
 
En fait j'ecris l'adresse dans un char* (un tableau d'octets) que j'envoie a un autre processus par MPI. Cet autre processus doit retrouver la bonne adresse a partir de l'ancienne grace a un map :
 
map<const void*,Objet*>
 
Pour ecrire et lire dans un tableau d'octet j'ai mon propre stream avec un Add et un Sub comme tu peux le voir au dessus..
Je ne sais pas pourquoi l'adresse que j'ecris dans le tableau est par exemple 0x2006ee48 et celle que je lis est  0x2006ee4800000000, d'apres ce que tu dit les premiers octets de l'adresse sur 64 bits sont des zeros et ne sont pas écris par cerr.  Je vais regarder ca en détail.
 
Ce qui est etrange c'est qu'il n'ya pas de problèmes pendant un certain temps et que je ne vois pas de différences entre la ou ca marche et la ou ca bug ....
 
Merci en tout cas !!


Message édité par nastymushroom2 le 01-01-2011 à 23:20:33
Reply

Marsh Posté le 03-01-2011 à 21:07:19    

Ton histoire c'est pas fantastique en terme d'alignement.
 
value = ((T*) temp)[0];
 
rien ne garantit que ton char* est correctement aligné pour un T, et sur certains architectures, ça te serait fatal.

Reply

Marsh Posté le 03-01-2011 à 21:14:40    

Taz a écrit :

Ton histoire c'est pas fantastique en terme d'alignement.
 
value = ((T*) temp)[0];
 
rien ne garantit que ton char* est correctement aligné pour un T, et sur certains architectures, ça te serait fatal.


 
Pourrais tu préciser ce que tu entend par alignement ? Si je met 5 fois un octet dans un tableau de 5 octets et qu'ensuite je lis ca comme un tableau de 1 objet de taille 5...
Enfin je serais heureux d'ameliorer mon code ...
 
Merci

Reply

Marsh Posté le 12-01-2011 à 12:31:08    

c'est quoi, SubChar ?
Sinon, j'en remets une couche sur ce que Taz dit : pourquoi faire un new char[ sizeof( T ) ] plutôt que de faire un new T que tu reinterpret_casteras éventuellement plus tard en char* si tu as besoin d'aller voir ses tripes ?


---------------
last.fm
Reply

Marsh Posté le 03-02-2011 à 22:38:19    

theshockwave a écrit :

c'est quoi, SubChar ?
Sinon, j'en remets une couche sur ce que Taz dit : pourquoi faire un new char[ sizeof( T ) ] plutôt que de faire un new T que tu reinterpret_casteras éventuellement plus tard en char* si tu as besoin d'aller voir ses tripes ?


 
 
SubChar prend le caractere suivant de mon tableau de caractere ....
 
 

Code :
  1. char binstream::SubChar(){
  2. ptr++;
  3. return val[ptr-1];
  4. }


 
 
Pourquoi je ne fais pas un new T ? Je ne sais pas, alors j'essaie ca donnerais ca :
 

Code :
  1. template<class T>
  2. void Sub(T& value)  {
  3.  T* ret = new T;
  4.  char* temp = (char*) &ret;
  5.  for (unsigned int i=0; i<sizeof(T); i++)    {
  6.   temp[i] = SubChar();
  7.  }
  8.  value = *ret;
  9.  delete[] ret;
  10. }


 
 
 
A vrai dire je pense avoir une fuite de memoire quelque part la dedans ....

Reply

Marsh Posté le 03-02-2011 à 22:43:06    

Oui, mon erreur venait de mon template, j'inserais un long int et je reccuperais un int donc je decalais toute ma lecture ....
 
Maintenant je chasse les fuites de memoires
 
J'ajoute le code de Add et Sub specifiques aux string
Si vous voyez l'erreur ou une optimisation
 

Code :
  1. void binstream::AddString(string value)  {
  2. unsigned int stringsize = value.size();
  3. Add(stringsize);
  4. const char* temp = value.c_str();
  5. for (unsigned int i=0; i<stringsize; i++)    {
  6.  AddChar(temp[i]);
  7. }
  8. }
  9. string binstream::SubString()  {
  10. unsigned int stringsize;
  11. Sub(stringsize);
  12. char* temp = new char[stringsize];
  13. for (unsigned int i=0; i<stringsize; i++)    {
  14.  temp[i] = SubChar();
  15. }
  16. string ret(temp,stringsize);
  17.  delete[] temp;
  18. return ret;
  19. }

Reply

Sujets relatifs:

Leave a Replay

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