Manipulation de std::vecteur probleme memoire

cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006 - 28 juil. 2006 à 19:23
cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006 - 3 août 2006 à 18:34
Bonjour a tous!


Je suis confronte a de serieux problemes avec la manipulation des std::vector en c++ avec Visual .Net 2003. J' ai developpe un algorithme qui doit gerer des listes d objets assez complexes j utilise donc des vector pour les stocker.


Jusque la pas trop de probleme mais par la suite j ai tente d integrer mon algorithme a un autre projet que j ai adapte et les methodes communiquent par le biais de std::vector< std::vector > de maniere iterative. Mais mon programme fini par s arreter pour cause de probleme de memoire de ce type:


Microsoft C++ exception: std::bad_alloc @ 0x0012ecac.


Y a t-il un probleme connu avec le fait d envoyer d envoyer en parametres des pointeurs sur des std::vector et de retourner des objets de type std::vector par le biais de methodes d'objet ou de methode statique.


Voici un exemple de code contenue dans une methode appele de facon iterative:


        std::vector mvRef;
 int num4x4Blocks = width/4*height/4;
 blocks4x4.reserve(num4x4Blocks);
 mvRef.reserve(2*num4x4Blocks);
      
        //
        //
        // Insertion des valeurs dans mvRef a l'aide de differentes
        // methodes
        //
        //


        
        return mvRef;    // Ceci cree une erreur de type memory a la 2 eme
                                  // iteration


 




Toutes vos suggestions sont les bienvenues...

13 réponses

steve_clamage Messages postés 475 Date d'inscription dimanche 3 octobre 2004 Statut Membre Dernière intervention 11 août 2006 5
28 juil. 2006 à 20:00
bad_alloc est levée quand l'allocation via new (ou un autre allocateur)
échoue. Ca peut etre une fatalité (tout a une limite) mais dans ton
exemple, si num4x4Blocks est élevé, tu sature inutilement la mémoire en
retournant mvRef par valeur.

Le mieux c'est de le passer par référence pour le modifier dans la
fonction. Ou alors sans changer le code tu peux faire dans le code
appelant

std::vector v; // vector vide

v.swap(methode()); // methode() retournant mvref


en réglant les optimisations du compilateurs au max il est possible
d'éviter ainsi la copie inutile, on appel ca RVO (Return Value
Optimization).
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
28 juil. 2006 à 20:02
Tant que tu détruits pas d'élement du vector pendant une boucle ou que
tu initialises des pointeurs sur des entiers du vector. Je pense pas
que tu peux avoir de pb particulier. Mais utilise le debugger pour
avoir des précisions.


AH, je viens de noté, tu confonds pas reserve et resize par hasard ?
Reserve n'alloue pas la mémoire. Dans ton cas je crois que c'est plutot
resize, que tu veux.
0
steve_clamage Messages postés 475 Date d'inscription dimanche 3 octobre 2004 Statut Membre Dernière intervention 11 août 2006 5
28 juil. 2006 à 20:08
reserve() alloue la mémoire, mais il ne construit rien.
0
cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006
28 juil. 2006 à 23:36
J'ai essaye ta solution avec la fonction swap(), steve, mais malheureusement ca ne change rien. C'est comme si il n'y avait plus assez de memoire pour autoriser le renvoi du vecteur. Y a t'il un nombre limite de vecteur qu on puisse utiliser? mon programme en contient plusieurs dans differse classe toutes d une valeur de l ordre de la 10aine de milliers... certaine sont declaree localement d' autres sont des instances privees ou public de classe dont les affectations se font par des methodes de type set(*v) ou *v est un pointeur vers un vecteur envoye en parametre
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
29 juil. 2006 à 14:39
Et avec resize ? ...
0
cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006
29 juil. 2006 à 14:47
ben comme l'a dit Steve reserve alloue de la memoire, de telle sorte qu au moment ou les objets sont inseres dans le vecteur aucune autre operation d'allocation de memoire n'est a etre effectuee
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
29 juil. 2006 à 17:10
Mais c'est pas ce que je demande. Reserve ne modifie pas la taille du
vector alors que resize si. Lui il confond les deux. En voulant faire
resize, il utilise reserve.
0
cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006
29 juil. 2006 à 17:32
Je ne veux pas faire resize. Je ne tiens pas a modifier la taille du vecteur mais bel et bien a reserver de l'espace memoire parce que je sais d'ores et deja qu il aura num4x4Blocks elements. De toute maniere je ne vois pas ce que resize pourrait avoir comme rapport avec un probleme de memoire vu qu il sert a redefinir la taille d un vecteur en supprimant ou ajoutant des elements pour que le vecteur possede la taille specifiee avec resize
0
cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006
29 juil. 2006 à 17:37
En quelque sorte je crois que reserve est une securite pour etre sur que l insertion d un nouvel element dans le vecteur ne cause pas de probleme de manque de memoire lors de l'allocation dynamique. Car de toute evidence l espace memoire reserve lors de la creation d un vecteur n est pas suffante pour stocker une 10aine de milliers d objet tel que les miens. En gros, en faisant un reserve je m assure qu il y ait assez de memoire libre. Maintenant peut etre devrai-je faire egalement un resize mais je ne pense pas qu il soit necessaire de specifier la taille du vecteur lorsque celui-ci est encore vide
0
steve_clamage Messages postés 475 Date d'inscription dimanche 3 octobre 2004 Statut Membre Dernière intervention 11 août 2006 5
29 juil. 2006 à 22:14
Oui entre autre, reserve permet aussi d'enchainer les push_back avec
plus d'efficacité, d'éviter de trop nombreuses petites allocations qui
peuvent être trés pénalisantes suivant l'allocateur.

Pour en revenir à ton problème, tu as éssayé en passant le vector par
référence et en le modifiant dans la fonction, plus généralement il
faut éviter toutes copies inutiles de gros vecteur si c'est un problème
de saturation du tas.
0
cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006
29 juil. 2006 à 22:43
Oui tu as tout a fait raison il est preferable de passer les references plutot qu une copie de l objet comme je le fait la
0
cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006
29 juil. 2006 à 23:37
J'ai modifier mon code en ne passant que des references cette fois-ci et non pas des copies de vecteurs comme je le faisait avant mais l erreur de memoire est revenue au niveau du


return mvRef;


mais a la  1ere iteration cette fois ci. C est a ni rien comprendre!!!!!!!
0
cs_angediablo Messages postés 8 Date d'inscription dimanche 16 juillet 2006 Statut Membre Dernière intervention 3 août 2006
3 août 2006 à 18:34
Finalement je me suis resigne a utilier un tableau de pointeurs a la place des vecteurs car meme n utilisant que du referencement ( c est a dire en ne transmettant jamais une copie d un objet envoye en parametre a une methode mais plutot la reference de ce dernier)  et ca plante moins facilement. Mais comme mon programme est engage dans un boucle qui devrais selon les cas atteindre jusqu a un maximum de 1000 iterations environ, Je fini tout de meme par avoir un runtime error et mon programme se voit forcer d etre interrompu par le system. Pourtant ma contribution n est qu un plug in a un soft qui tourne deja sans aucun probleme meme avec plus de 1000 iteration. Je sais que la coquille vient de mon bout de code mais ou exactement? aucune idee. Je crois avoir tout essaye. Cependant j ai remarque un phenomene bizarre: lorsque la reference a **blocks est envoye en paremetre (&blocks) a une methode qui ne fait que de lire les valeurs pointee sans en modifier aucune elles sont alteree des la fin de l execution de la methode. D ou peut venir ce genre de phenomenes en general?
0
Rejoignez-nous