Pb d'"allocation mémoire avec STL string

Pb d'"allocation mémoire avec STL string - C++ - Programmation

Marsh Posté le 13-11-2002 à 12:06:53    

Voila mon problème, ca fait maintenant un moment que je suis sur ce problème d'allocation mémoire, et le commence sérieusement à être a cours d'idée.
 
je travaille dans mes classes avec des liste de string déclrées comme suit
 

Code :
  1. #include <string>
  2. #include <list>
  3. #include <fstream>
  4. using namespace std;
  5. typedef list<string> liste_string;


 
Ainsi je peux allègrement passer mes données texte à mes différents objets sans problèmes.
 
Je suis récemment passé à la version 6 de builder. Je suis incapable de dire cet élément ( le passage à la STL port ) est à prendre a compte pour le problème suivant :
 
une erreur d'exception ( Voilation d'accès ... à l'adresse .... )
lors d'un push_back dans une liste de string :
 

Code :
  1. for ( liste_string::iterator itDim = (Temp.begin()) ;
  2.                                  ( (itDim != Temp.end()) && ( !FinParcours ) );
  3.                                   itDim ++                                     )
  4. {
  5.   // détection de la barre de séparation
  6.   if ( !strcmp( ( itDim->substr( 1,itDim->length()-1 )).c_str() ,
  7.                 ( string( itDim->length(),'-') ).c_str()            )    )
  8.         FinParcours = true ;
  9.   // si la ligne est valide et contient au minimum 13 caractères
  10.   if ( (!FinParcours) && (itDim->length() > 13) )
  11.   {
  12.    // conversion des dimensions de la fiche vers le même format que celui
  13.    // indiqué sur CompilLig afin de pouvoir les comparer
  14.    // les dimensions converties sont placées dans un string formaté sous 9c
  15.    // dont le premier renseignera sur sa non disponibilité dans la fiche
  16.    str = " " ;
  17.    tmp = ConvertirDimension( itDim->substr(1,6) );
  18.    str += RetournerEspace( 4,tmp.length() );
  19.    str += tmp ;
  20.    tmp = ConvertirDimension( itDim->substr(7,6) );
  21.    str += RetournerEspace( 4, tmp.length() );
  22.    str += tmp ;
  23.    // Insertion dans la liste
  24.    [color=red]DimFiche.push_back(str);[/color]
  25.   }
  26. }


le code ci dessus se charge juste de vérifier la présence d'éventuels doublons et de gérér l'ajout d'une nouvelle  entrée à la liste en remplaçant la 1° lettre du nouveauy string par une astérique
 
la pile d'appel donne les informations suivantes :

Code :
  1. 77F863BA ntdll.dll
  2. 004031B3 _STL::__node_alloc<1, 0>::allocate(__n=14)
  3. 00402791 _STL::allocator<char>::allocate(this=:008C7E04, __n=14,  =NULL)
  4. 004041B5 _STL::_String_base<char, _STL::allocator<char> >::_M_allocate_block(this=:008C7DFC, __n=14)
  5. 00403450 _STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> >::_M_range_initialize<char *>(this=:008C7DFC, __f=:00922CF4, __l=:00922D01,  =:0012F134)
  6. 00402DCC _STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> >::_M_range_initialize<char * const>(this=:008C7DFC, __f=:00922CF4, __l=:00922D01)
  7. 00402D9F _STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> >::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> >(this=:008C7DFC, __s=:0012F38C)
  8. 00403FED _STL::_Construct<_STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> >, _STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> > >(__p=:008C7DFC, __value=:0012F38C)
  9. 00403EFA _STL::list<_STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> >, _STL::allocator<_STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> > > >::_M_create_node(this=:0012F3C4, __x=:0012F38C)
  10. 00403A09 _STL::list<_STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> >, _STL::allocator<_STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> > > >::insert(this=:0012F3C4, __position={ :008C6020 }, __x=:0012F38C)
  11. 004064CA _STL::list<_STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> >, _STL::allocator<_STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> > > >::push_back(this=:0012F3C4, __x=:0012F38C)
  12. 0041A298 GestionRequis::EnumererDimensions(this=:008AEF64, ContenuFicheArt={ { :008C72C0 } }, CodeArticle={ "L05M300CB", "", { "   -" } })
  13. 00415F0C GestionRequis::TraiterFicheContenuQuantitatif(this=:008AEF64, ContenuFiche={ { :008C72E0 } }, TypeArticle={ "A", "", { "?" } }, CodeArticle={ "L05M300CB", "", { "3002" } })
  14. 00419761 GestionRequis::TraiterFiche(this=:008AEF64, CodeArticle={ "L05M300CB", "", { "" } })
  15. 0041A847 GestionRequis::Requisitions(this=:008AEF64)
  16. 00401AAB main(argc=1, argv=:008A542C)


 
je précise avoir essaye de changer ce morecau de code d'emplacement , de méthode.
 
les string contiennent bien des valeurs et la liste et bien initialisée.
La méthode ne plante pas à sa première execution....
 
 
le debugger pointe la méthode allocate du fichier _alloc.h

Code :
  1. static void * _STLP_CALL allocate(size_t __n) { return (__n > (size_t)_MAX_BYTES) ?  __stl_new(__n) : _M_allocate(__n); }


 
je ne pense pas qu'il soit terriblement utile d'essayer de refaire ce code
puisque des parcours de liste de string en ce genre sont déja en place dans mon programme en divers endroit et fonctionnement parfaitement.
 
Merci pour vos suggestion.  :oops:

Reply

Marsh Posté le 13-11-2002 à 12:06:53   

Reply

Marsh Posté le 14-11-2002 à 03:02:16    

Code :
  1. !strcmp( (itDim->substr(1,itDim->length()-1)).c_str() , (string(itDim->length(),'-')).c_str() ) //ceci...
  2. itDim->substr(1,itDim->length()-1) == string(itDim->length(),'-') //..est simplifiable.

Et à mon avis, il y a encore moyen de simplifier.
Je me pose la question: pourquoi 1 et -1 ?
Les strings commençant à 0, j'en déduis que les séparateurs sont une suite de '-', sauf les premiers/derniers.
Mais alors, la première séquence de longueur "length()-2" n'est jamais égale à la seconde de longueur "lenght()" ?
 
Détail:

Code :
  1. //Pourquoi faire compliqué...
  2. for ( /*...*/ ; /*...*/ && !FinParcours ; /*...*/)
  3. {
  4. if (/*...*/)
  5.  FinParcours = true ;
  6. if ( !FinParcours && /*...*/ )
  7.  /*...*/ ;
  8. }
  9. //...quand on peut faire simple ?
  10. for ( /*...*/ )
  11. {
  12. if (/*...*/)
  13.  break;
  14. if ( /*...*/ )
  15.  /*...*/ ;
  16. }


Sinon, je ne vois pas de problème... ni l'astérisque !


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 14-11-2002 à 14:38:06    

J'ai essayé de mettre un peu d'ordre dans tout ca...
 
L'erreur reste la même,  
mais l'endroit du code ou le plantage survient lui change....
 
Je n'ai rien fait de spécial pour ca  :??:  :??:  :??:  :??:  
 
je travaille sur une application console, est il possible que  
la mémoire vienne a être insuffisante ...
ou que l'allocation soit inefficace apres telle ou telle seuil,
...???!!
 
je suis a cours d'idées


Message édité par boborde le 14-11-2002 à 14:39:51
Reply

Marsh Posté le 15-11-2002 à 20:33:20    

A Y EST !! :-)
 
bon la méthode qui jetais l'exception ( celle dont g placé une partie du code dans le 1° post ) étais appelé plusieur fois par une boucle par la méthode pricipale de la classe.
 
Cette méthode principale , danse reste du corps de la boucle  
effectuée une concaténantion de liste de string
 
pour cela elle utilisait copy() qui n'ets pas une méthode du container liste...

Code :
  1. copy(listeA.begin(),listeA.end(),listeB.end());


 
ceci marchait avec Builder 5 ( stl rogue vave... je sais plus )
 
ceci dit pares l'appel a copy g decouvert que les varaibles de la méthode pricipale étai afféctées avec das valeurs coorrespondantes aux deux listes de string .....!!!
 
g échangé copy par un splice() du container
et ca marche tres bien
 
 
je pense que copy , du fait que la fonction n'utilise pas la gestion mémoire spécifiée par la classe allocator du template list<string>, ne pouvait pas covenablement creer deux nouveaux éléments avec la stlPort...??
 
je sais pas trop, j'espere qu'un jour je comprendrais mieux l'allocation de la stl
je vais m'y pencher dessus
 
 
4 jours de recherche... LOL
 
merci musaran pour ton aide

Reply

Marsh Posté le 15-11-2002 à 23:33:12    

container::end() est un non-élément, je suis pas sur qu'on ait le droit de le spécifier comme destination.
Surtout pour une liste chaînée qui doit allouer chaque élément.
 
Je crois que c'est back_inserter ou push_back qu'il faut utiliser.
 
Mais comme j'ai pas encore utilisé tout ça, c'est flou pour moi.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 15-11-2002 à 23:34:53    

pourquoi utilsier strcmp à la place de less?


---------------
du bon usage de rand [C] / [C++]
Reply

Sujets relatifs:

Leave a Replay

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