pb avec gestion memoire

pb avec gestion memoire - C++ - Programmation

Marsh Posté le 03-08-2005 à 12:22:10    

Salut,
 
Alors que je pensais faire un prog tout simple qui lit dans un fichier, j'ai eu ce probleme.
le prog lit dans un fichier les lignes qu'il trouve. Un jeu de donnees se compose d'un titre commençant par '!' et des donnees (ici du texte, mais peut-etre des donnees bianires).
 
A l'aide du debugger ddd, je vois que la chaine _s n'est pas effacee.
 

Code :
  1. #include <iostream>
  2. #include <fstream> //ifstream = lecture fichier
  3. using namespace std;
  4. class B{
  5. public:
  6. char* _s;
  7. string _str;
  8. B(char* chaine="" ){
  9.  _str = string (chaine);
  10. //   _s = (char*) malloc(2560*sizeof(char));
  11.  _s = new char[2560];
  12.  cout << "qllocation de _s\n";
  13. }
  14. ~B(){
  15.  cout << "dstr A\n";
  16. /*  if(s)
  17.   free(_s);*/
  18.  delete[] _s; //n'efface rien en memoire
  19.  _s = NULL; //sans ca, _s toujours actif
  20. }
  21. };
  22. B* Bload(ifstream &fe)
  23. {
  24. char line[256];
  25. char x;
  26. char* ptr = &x;
  27. B* b = NULL;
  28. while(fe.get(*ptr))
  29. {
  30.  if(*ptr=='!')
  31.   if(b == NULL)
  32.   {
  33.    fe.getline(line, 256);
  34.    b = new B(line);
  35.    ptr = b->_s;
  36.   }
  37.   else
  38.   {
  39.    fe.unget();
  40.    break;
  41.   }
  42.  else if(*ptr != '\n')
  43.  {
  44.   if(b == NULL)
  45.    b = new B();
  46.   ptr++;
  47.  }
  48. }
  49. cout << "b->_str = " << b->_str
  50.  << "\tb->_s = " << b->_s << endl;
  51. return b;
  52. }
  53. int main(void)
  54. {
  55. int i;
  56. ifstream fe("dat.txt" );
  57. B* b = NULL;
  58. for(i=0; i<3; ++i)
  59. {
  60.  b = Bload(fe);
  61.  delete b; //marche pas correctement
  62. }
  63. return 0;
  64. }


et le fichier dat.txt

!1e serie de donnees1
ici les premieres donnees rencontrees
sur plusieurs lignes
!donnees 2.
la se trouvent les donnees de la 2e serie
!derniere serie
enfin je termine ici


Merci de m'eclairer sur ce pb de memoire.
 
KooK


Message édité par KooK le 03-08-2005 à 12:25:29
Reply

Marsh Posté le 03-08-2005 à 12:22:10   

Reply

Marsh Posté le 03-08-2005 à 12:55:39    

#         delete[] _s;    //n'efface rien en memoire
#         _s = NULL;    //sans ca, _s toujours actif
 
si si ça efface.
 
# char x;
#     char* ptr = &x;
 
... c'est compliqué tout ça ...
 
 
ça veut dire quoi marche pas ? ton programme est assez dégueux, avec une indentation pas clair du tout.
 
 
je conclue : n'utilise qu'std::string

Reply

Marsh Posté le 03-08-2005 à 13:29:51    

std::string pas question, pour stocker des donnees binaires c'est pas terrible.
l'indentation est tres bonne.

Code :
  1. char x;
  2. char *ptr = &x;


c'est pour stocker le caractere lu tant que je ne sais pas ce que je lis.
 
Et si le delete est correct, alors pourquoi j'ai la sortie suivante :
"qllocation de _s
b->_str = 1e serie de donnees1  b->_s = ici les premieres donnees rencontreessur plusieurs lignes!
dstr A
qllocation de _s
b->_str = donnees 2.    b->_s = la se trouvent les donnees de la 2e serie!
dstr A
qllocation de _s
b->_str = derniere serie        b->_s = enfin je termine icionnees de la 2e serie!
dstr A "
 ?


Message édité par KooK le 03-08-2005 à 13:33:01
Reply

Marsh Posté le 03-08-2005 à 13:47:23    

bien sur ! std::string est toute indiquée pour stocker des données binaires ! tu peux aussi utilise un std::vector.
 
mais si t'es si malin que ça, t'as qu'à correctement terminée tes chaines par un '\0' (comprendre que tes données ne sont donc pas binaire, et qu'ici tu dois te cogner ce problème à la main)
 
 
 
    * char x;
    * char *ptr = &x;
 
ptr te sert à rien, c'est l'assombrissement de code.
 
ptr++;
 
j'espère qu'ici t'es bien sur de plus pointer sur x ... ou de ne pas dépasser les borne de ptr = b->_s;
 
cherche pas, t'es dans les décor.
 
utilise std::string

Reply

Marsh Posté le 03-08-2005 à 14:01:10    

le delete libère juste la mémoire utilisée ... si tu utilises _s après avoir fait le delete, tu n'as aucune garantie quant au contenu de la zone mémoire pointée par _s.

Reply

Marsh Posté le 03-08-2005 à 15:41:13    

Je crois que je viens de comprendre, en fait tout se passe normalement et si j'ai ce bout de phrase collé à la nouvelle, c'est justement parce que la mémoire a été réutilisée et comme je n'ai pas de symbole de fin fin de chaine, il affiche tous jusqu'à en rencontrer un.
 
Une erreur de débutant quoi !
 
->Tazounet, c'est aussi un peu grâce à toi que j'ai compris, mais un peu de douceur, de finesse, de diplomatie que diable. =>"un char* dans un flux affichera tous les caractères jusqu'au premier '\0' rencontré" eu été une réponse tellement plus courtoise et pédagogue.
 
Problème résolu.
KooK

Reply

Marsh Posté le 03-08-2005 à 15:45:03    

bah c'est toi qui sort une sentence sur le string ! alors si apres il faut repartir au "un char* est délimité par un '\0'", c'est difficile de savoir par où commencer.
 
La mémoire est pas réutilisée, c'est exactement là même. Donc si tu t'amuses à change certains caractères au début, la fin reste la même.
 
 
Allez vire TOUS tes char*

Reply

Sujets relatifs:

Leave a Replay

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