IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Problème pour vider un vector . ..


Sujet :

C++

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2012
    Messages : 8
    Par défaut Problème pour vider un vector . ..
    Bonsoir !

    Alors voilà, j'ai un souci pour vider mon vector, j'ai essayé avec .clear() .erase() . . .etc, rien ne fonctionne, le vecteur est toujours là . . .

    C'est dans le cadre de la "gestion" d'un univers, donc il y a un vecteur galaxies, qui contient des vecteurs systèmes solaires, qui contiennent des vecteur planètes, qui eux même contiennent d'autres vecteurs . . .


    Bref, En gros ça "s'architecture" comme cela:

    std::vector<CGalaxie>.std::vector<CSystemeSolaires>.std::vector<CPlanete>



    Mon objectif, c'est de supprimer tout les vecteurs planètes.

    Pour ce faire, je fais comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void CJeu::ViderVecteursPlanetes()
    {
        int j2=Galaxie.SystemeSolaires.size(); //Je récupère le nombre de systèmes 
        while(j2>0)
        {
            for(int i=Galaxie.SystemeSolaires[j2].Planetes.size();i!=0;i--)
            {
                Galaxie.SystemeSolaires[j2].Planetes.clear();
            }
            j2--;
        }
    }
    Evidemment ça ne fonctionne pas.

    AUCUNE altération de la mémoire utilisée, alors que .clear() est sensé appeler le destructeur des objets "Planetes", et donc détruire l'objet, hors . . . rien.


    Et l'objet existe toujours, étant donné que je peux toujours y accéder . . .

    Peut-être que j'ai mal rempli les vecteurs ?

    J'ai fais comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    *CPlanete PlaneteTemporaire = new CPlanete();
    Planetes.push_back(*PlaneteTemporaire); //C'est un std::vector<CPlanete> Planetes
    delete PlaneteTemporaire;


    Bref, je sèche, j'ai fais une erreur, mais où ?

    Merci de votre aide

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Utiliser new n'a aucun intérêt ici.

    Tu peux soit faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Planete t;
    Planetes.push_back(t);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Planetes.push_back( Planete() );
    Sinon es-tu bien sûr que les destructeurs ne sont pas appelés? (mettre un std::cerr << "planete : arg je me meurs" << std::endl; dans le destructeur de ta classe Planete devrait nous donner la réponse).
    Clear ne va pas modifier la mémoire il va tout simplement mettre le nombre d'élément à 0 (et normalement appeler le destructeur pour chaque objet stocké) mais garder la même capacité (?).
    Si tu veux libérer la mémoire prise par ton vecteur, soit il faut que te le détruise, soit il faut que tu appelles std::vector::resize(unsigned int).

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2012
    Messages : 8
    Par défaut
    Merci pour ta réponse.

    En fait si, j'ai besoin d'un new(), car je passe des données au constructeur (je ne l'ai pas mis ici par soucis de clarté)

    Pour effacer le vecteur, j'ai également essayé ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Galaxie.SystemeSolaires[i].Planetes.erase(Galaxie.SystemeSolaires[i].Planetes.begin(),Galaxie.SystemeSolaires[i].Planetes.end());
    (i permettant de parcourir tous les Systemes Solaires)

    Et ça ne vide pas non plus la mémoire.

    Pour le cas de resize, je viens d'essayer mais je rencontre une erreur de compilation, je vais voir un peu sur le net le pourquoi du comment, mais faire un resize(0) revient au même à faire un erase non ?

  4. #4
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    clear efface les élements du vector (cf http://www.cplusplus.com/reference/vector/vector/clear/ )
    C'est à dire que si c'est un POD (int, double, etc...), alors c'est simplement effacé. Bref, normal quoi.
    Si c'est une instance de classe, le destructeur est appelé.
    Par contre, si les éléments du vecteur sont des pointeurs, ça efface le pointeur, mais pas l'objet pointé. Fuite mémoire garantie.

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Soporythmique Voir le message
    Merci pour ta réponse.

    En fait si, j'ai besoin d'un new(), car je passe des données au constructeur (je ne l'ai pas mis ici par soucis de clarté)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Classe c1(param1, param2, param3);
    fonction(c1);
     
    fonction( Classe(param1,param2, param3) );

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Par défaut
    Je ne comprends pas le sens de la boucle sur "i" ? Tu parcours les éléments du vector que tu veux vider ?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<CGalaxie>.std::vector<CSystemeSolaires>.std::vector<CPlanete>
    Dans ton code tu n'index pas le premier vector ? (Et les variables globales c'est mal )

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 152
    Billets dans le blog
    4
    Par défaut
    Bonjour,
    Citation Envoyé par Soporythmique Voir le message
    AUCUNE altération de la mémoire utilisée, alors que .clear() est sensé appeler le destructeur des objets "Planetes", et donc détruire l'objet, hors . . . rien.


    Et l'objet existe toujours, étant donné que je peux toujours y accéder . . .
    Tu te méprends sur le clear et l'appelation de "destructeur".
    Ton vecteur ne contient pas des Planetes mais des pointeurs sur Planetes.
    Et tout comme pour un int, le destructeur d'un pointeur ne fait rien, et encore moins un appel au destructeur des données pointées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void CJeu::ViderVecteursPlanetes()
    {
        int j2=Galaxie.SystemeSolaires.size(); //Je récupère le nombre de systèmes 
        while(j2>0)
        {
            for(int i=Galaxie.SystemeSolaires[j2].Planetes.size();i!=0;i--)
            {
                Galaxie.SystemeSolaires[j2].Planetes.clear();
            }
            j2--;
        }
    }
    Ce code, le comprends-tu ?
    Tu fais une boucle sur Galaxie.SystemeSolaires[j2].Planetes.size() pour... y faire un clear à la première itération. Ta boucle ne fera jamais plus d'une itération.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void CJeu::ViderVecteursPlanetes()
    {
        int j2=Galaxie.SystemeSolaires.size(); //Je récupère le nombre de systèmes 
        while(j2>0)
        {
            for(int i=Galaxie.SystemeSolaires[j2].Planetes.size();i!=0;i--)
            {
                delete Galaxie.SystemeSolaires[j2].Planetes[i];
            }
            Galaxie.SystemeSolaires[j2].Planetes.clear();
            j2--;
        }
    }
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2012
    Messages : 8
    Par défaut
    Merci pour vos réponses

    Ha ouais effectivement la boucle i ne sert à rien, j'ai essayé tellement de trucs que je me suis emmêlé les pinceaux avec pop_back() apparemment

    Donc du coup, comme vous me l'avez, a raison, fait remarquer, le new() ne servant à rien, je l'ai remplacé par la declaration d'un objet CPlanete(), donc exit le problème de pointeur, et plus besoin de delete.

    Donc du coup, ceci devrait fonctionner: ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void CJeu::ViderVecteursPlanetes()
    {
        int j2=Galaxie.SystemeSolaires.size(); //Je récupère le nombre de systèmes 
        while(j2>0)
        {
                Galaxie.SystemeSolaires[j2].Planetes.clear();
            j2--;
        }
    }

    Oui, vous l'avez compris, si je demande, c'est parce que ça ne fonctionne toujours pas, j'ai toujours accès aux données des différentes planètes

    Pour la création des objets planètes, en retirant le new ça donne ça désormais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Planetes.push_back(CPlanete(Param 1, Param 2 . . . , Param n))
    Sinon, (peut-être que le problème viendrait de là) après avoir créé mes objets CSystemes et CPlanètes, je classe les systèmes selon la valeur de leur coordonnées (seulement la X pour le moment), ce qui me donne un code comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void CGalaxie::Trier()
    {
        std::sort(SystemeSolaires.begin(), SystemeSolaires.end());
    }
    Avec dans le CSystemeSolaires.h ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    friend bool operator < (const CSystemeSolaire &lhs, const CSystemeSolaire &rhs)
        {
            return (lhs.CoordonneesX < rhs.CoordonneesX ? true : false);
        }
    Ca fonctionne, CEPENDANT, j'ai remarqué qu'après cette étape, l'utilisation de la mémoire est DOUBLÉE, j'ai beau chercher je ne vois pas pourquoi . . .

    Pourquoi je vous parle de ça ?

    Peut-être que comme ça a attrait à la mémoire, le problème serait lié ?

    Mouarf là je sèche totalement sur ces deux points (qui sont peut être liés du coup ...)

  9. #9
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Hum...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void CJeu::ViderVecteursPlanetes()
    {
        Galaxie.SystemeSolaires.clear();
    }
    Quand tu vides ton vecteur de SystemeSolaires, que crois tu que deviens tes planètes ?


    Sinon, plusieurs choses m'embêtes dans tes codes...

    1. non respect de la sémantique d'entité -> il vaudrait mieux des vector<unique_ptr<...>>

    2. non respect de Déméter -> il ne faudrait pas pouvoir accéder au type CSystemeSolaires depuis le type CGalaxie et pas au type CPlanete depuis CSystemeSolaires. Dans ton cas par exemple, tu devrais avoir simplement un Galaxie.clear() (lui même vidant le vecteur de CSystemeSolaires, et chaque destruction de CSystemeSolaires la vidange des vecteurs de Cplanete)

    3. Pourquoi while plutôt que for ?

    4. (re)lis un cours sur vector (, ou )

    5. Tu as également un problème avec les constructeurs et destructeurs, relis un cours là dessus

    6. Idem pour l'utilisation de new et des pointeurs, relis un cours aussi la dessus
    En particulier, tu comprends ce que ton code suivant fait ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    *CPlanete PlaneteTemporaire = new CPlanete();
    Planetes.push_back(*PlaneteTemporaire); //C'est un std::vector<CPlanete> Planetes
    delete PlaneteTemporaire;
    7. Bon, t'embêtes pas, lis un cours complet de C++, ça sera plus simple

    8. Quelles sont les responsabilités de tes classes (les services qu'elles doivent rendre) ? Si CGalaxie et CSystemeSolaires ne font rien d'autre que de contenir des CPlanete, des typedef sont suffisants

    9. Pourquoi le C dans les noms de classes : CGalaxie, CSystemeSolaires, CPlanete ? Tu essaies de copier Qt et ses noms de classes avec des Q partout ? Mauvaise idée de copier Qt... Utilise un namespace

    10. Comment tu le sais ? (et me répond pas "grâce au gestionnaire de tâches de windows"...)
    l'utilisation de la mémoire est DOUBLÉE
    11. "CoordonneesX " ? Pourquoi faire simple quand on peut faire compliqué... "x" c'est pas mieux ? Plus généralement, j'aime pas les noms de classes/fonctions en français...

    @Bousk
    Non, c'est bien un vecteur sans pointeur... l'utilisation de new t'a trompé
    (mais effectivement, faudrait utiliser des vecteurs de pointeurs)

  10. #10
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void CJeu::ViderVecteursPlanetes()
    {
        int j2=Galaxie.SystemeSolaires.size(); //Je récupère le nombre de systèmes 
        while(j2>0)
        {
                Galaxie.SystemeSolaires[j2].Planetes.clear();
            j2--;
        }
    }
    Pourquoi chercher les complications en voulant effacer les planètes à l'envers ? (En plus il y a un bug l'indice j2 ne passe jamais à zéro.)
    Une boucle for classique est suffisante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int i = 0 ; i < Galaxie.SystemeSolaires.size(); i++)
    {
         Galaxie.SystemeSolaires[i].Planetes.clear();
    }
    Citation Envoyé par Soporythmique
    Oui, vous l'avez compris, si je demande, c'est parce que ça ne fonctionne toujours pas, j'ai toujours accès aux données des différentes planètes
    Qu'est-ce que tu veux dire par "j'ai toujours accès aux données des différentes planètes" ?

    Si tu veux vérifier que les clear ont bien marché alors tu peux par exemple boucler sur les système solaires et afficher la taille du vecteur planète :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Galaxie.SystemeSolaires[i].Planetes.size()
    Si toutes les tailles sont bien à zéro alors les clear ont marché. Attention si size() renvoie zéro mais que tu essayes quand même d'accéder au vector (par exemple en faisant Galaxie.SystemeSolaires[i].Planetes[j]) alors c'est un BUG. Il ne faut pas essayer d'accéder à un vecteur de taille nulle, le résultat est indéterminé et peut renvoyer n'importe quoi. Dans ton cas ça peut sembler marcher car si tu accèdes aux données d'une planète juste après un clear l'OS n'a probablement pas encore eu le temps de réutiliser la zones mémoires associée pour autre chose.

  11. #11
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2012
    Messages : 8
    Par défaut
    Merci pour vos réponses, et désolé du retard

    Alors, je vais répondre point par point comme ça ce sera plus simple.

    Sinon, plusieurs choses m'embêtes dans tes codes...

    1. non respect de la sémantique d'entité -> il vaudrait mieux des vector<unique_ptr<...>>
    Mmmmh, j'ai été voir, sans bien comprendre l'utilité d'un pointeur intelligent, quitte à devoir gérer un objet (sa destruction and co'), pourquoi devoir passer par un unique_ptr, autant le supprimer nous même ?

    2. non respect de Déméter -> il ne faudrait pas pouvoir accéder au type CSystemeSolaires depuis le type CGalaxie et pas au type CPlanete depuis CSystemeSolaires. Dans ton cas par exemple, tu devrais avoir simplement un Galaxie.clear() (lui même vidant le vecteur de CSystemeSolaires, et chaque destruction de CSystemeSolaires la vidange des vecteurs de Cplanete)
    Ouaip, mais, même si je te l'accorde c'est plus propre, pour ce vecteur je travaille comme ça, ça me simplifie les choses de travailler uniquement avec la classe "principale" pour les objets qui sont par la suite "dessinables", comme ça l'échange avec la classe CDessin s'en trouve plus simple, enfin c'ets comme ça que je PREFERE travailler, ce n'est pas la meilleure je le conçois


    3. Pourquoi while plutôt que for ?
    Parce que j'ai corrigé à l'arrache, et juste changé l'intérieur de la boucle et non la boucle elle même

    4. (re)lis un cours sur vector (là, là ou là)
    Je suis pas venu en touriste non plus hein ?, même si je suis pas un dieu de la programmation, j'ai quand même été voir ce qui était lié aux vecteurs ici, et également dans la section tuto de ce site

    5. Tu as également un problème avec les constructeurs et destructeurs, relis un cours là dessus
    Je te rassure je sais très bien comment ça fonctionne, c'est juste pour le constructeur, je ne me rappelais plus qu'on pouvait directement créer un objet en passant les paramètres, j'étais sûr qu'il fallait passer par un new(), ça faisait longtemps aussi faut dire . . ., enfin quoi qu'il en soit, j'ai quand même les bases

    6. Idem pour l'utilisation de new et des pointeurs, relis un cours aussi la dessus
    En particulier, tu comprends ce que ton code suivant fait ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    *CPlanete PlaneteTemporaire = new CPlanete();
    Planetes.push_back(*PlaneteTemporaire); //C'est un std::vector<CPlanete> Planetes
    delete PlaneteTemporaire;
    Bien sûr que je comprend, c'est quand même moi qui l'ai écrit.
    Création d'un pointeur pointant vers un objet CPlanete (on lui alloue la mémoire), ensuite on ajouter le contenu de ce pointeur (donc l'objet lui-même) à la fin du vecteur, pour ensuite supprimer le pointeur.

    Je sais que ça ne sert à rien, juste un mauvais souvenir comme dit au dessus, j'étais persuadé qu'il fallait passer par cet artifice, mais en fait non, l’erreur à été corrigée

    7. Bon, t'embêtes pas, lis un cours complet de C++, ça sera plus simple
    C'est pas très gentil ça

    8. Quelles sont les responsabilités de tes classes (les services qu'elles doivent rendre) ? Si CGalaxie et CSystemeSolaires ne font rien d'autre que de contenir des CPlanete, des typedef sont suffisants
    Non non, elles ont des utilités, le fait de contenir les vecteurs n'est que la surface émergée, j'ai des fonctions pour gérer le budget d'une planète . . . etc . . . , enfin j'ai besoin d'une classe.

    Ou dû moins, a mon niveau (qui n'est pas forcement très élevé je le conçois), je ne sais utiliser que des classes pour faire ça (Et puis ça me convient )

    9. Pourquoi le C dans les noms de classes : CGalaxie, CSystemeSolaires, CPlanete ? Tu essaies de copier Qt et ses noms de classes avec des Q partout ? Mauvaise idée de copier Qt... Utilise un namespace
    Je n'ai jamais utilisé Qt, c'est simplement mon prof d’algorithme en DUT qui nous avait appris à coder comme ceci, et c'est resté. Moi je trouve ça lisible, après ce code n'a pas pour vocation à être publié/lu par d'autres personnes, donc je code "à ma façon", après si c'était un code collaboratif l'utilisation de namespaces ou autre aurait été plus judicieuse c'est vrai.

    10. Comment tu le sais ? (et me répond pas "grâce au gestionnaire de tâches de windows"...)
    Citation:
    l'utilisation de la mémoire est DOUBLÉE
    Non non je te rassure
    Je le sais via le débuggeur, les trois "valeurs" (liées à la mémoire, je ne sais pas/plus comment on les appelles) d'un vecteur CPlanete sont TRES etranges.
    Exemple, AVANT de trier le vecteur, on à ceci:
    _M_start: 0x14709158
    _M_finish: 0x147093f8
    _M_end_of_storage: 0x147093f8

    Et après,
    _M_start: 0x14709158
    _M_finish: 0x147093f8
    _M_end_of_storage: 0x14709698

    On constate que la taille double ...
    Mais je crois avoir trouvé pour ce point, je vous tiens au courant

    11. "CoordonneesX " ? Pourquoi faire simple quand on peut faire compliqué... "x" c'est pas mieux ? Plus généralement, j'aime pas les noms de classes/fonctions en français...
    Alors là non, je suis pas d'accord du tout, je préfère LARGEMENT des noms en français, ça fait un peu "newbie", mais c'est tellement plus clair . . .
    (J'aurais pu mettre CooX à la limite)

    Et pour le second message:

    Pourquoi chercher les complications en voulant effacer les planètes à l'envers ? (En plus il y a un bug l'indice j2 ne passe jamais à zéro.)
    Une boucle for classique est suffisante :
    J'ai répondu au dessus du coup

    Qu'est-ce que tu veux dire par "j'ai toujours accès aux données des différentes planètes" ?

    Si tu veux vérifier que les clear ont bien marché alors tu peux par exemple boucler sur les système solaires et afficher la taille du vecteur planète :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Galaxie.SystemeSolaires[i].Planetes.size()
    Si toutes les tailles sont bien à zéro alors les clear ont marché. Attention si size() renvoie zéro mais que tu essayes quand même d'accéder au vector (par exemple en faisant Galaxie.SystemeSolaires[i].Planetes[j]) alors c'est un BUG. Il ne faut pas essayer d'accéder à un vecteur de taille nulle, le résultat est indéterminé et peut renvoyer n'importe quoi. Dans ton cas ça peut sembler marcher car si tu accèdes aux données d'une planète juste après un clear l'OS n'a probablement pas encore eu le temps de réutiliser la zones mémoires associée pour autre chose.
    Alors en effet, le vecteur est bien vider, quand je fais .size() j'obtiens bien 0.
    MAIS, la mémoire est toujours allouée, et quand je vais voir le contenu d'un des vecteurs CPlanete que je cherche à vider, j'ai ça:
    _M_start: 0x9b90020
    _M_finish: 0x9b90020 (Donc là on est OK, le vecteur CPlanete se vide bien au clear)
    _M_end_of_storage: 0x9c54020 (Et là, le drame, la mémoire reste allouée . . .)

    Où alors j'ai mal compris ?, ce qui est tout à fait possible vu mon niveau pas très élevé

    Bref, que je fasse .clear(), .erase(), ou même une boucle de pop_back(), toujours CE résultat, le end_of_storage est tout pourri.
    La cause de mon problème je pense, j'ai donc essayé de resize le vecteur, mais comme c'est une fonction que j'ai jamais utilisé, je vais voir ça sur la doc, je tente, et je vous dis quoi

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Par défaut
    clear() n'oblige pas le vector à libérer sa mémoire, heureusement d'ailleurs comme ça le prochain remplissage sera moins coûteux :-)

    Un swap pour forcer ? http://www.cplusplus.com/forum/beginner/32265/ et http://takinginitiative.net/2008/03/...s-memory-leak/

  13. #13
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Mmmmh, j'ai été voir, sans bien comprendre l'utilité d'un pointeur intelligent, quitte à devoir gérer un objet (sa destruction and co'), pourquoi devoir passer par un unique_ptr, autant le supprimer nous même ?
    Parce que
    1. donner la responsabilité de la mémoire à une classe RAII plutôt que le faire soi même évite les oublies et les erreurs
    2. le code est plus sur...
    Sur le code suivant que tu as donné, qu'est ce qui se passe en cas d'exception lors du push_back ? Le delete n'est pas appelé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    *CPlanete PlaneteTemporaire = new CPlanete();
    Planetes.push_back(*PlaneteTemporaire); //C'est un std::vector<CPlanete> Planetes
    delete PlaneteTemporaire;
    Donc le but est bien là : ne pas avoir à gérer soi même (par ce que soi même fait souvent des erreurs)

    Ouaip, mais, même si je te l'accorde c'est plus propre, pour ce vecteur je travaille comme ça, ça me simplifie les choses de travailler uniquement avec la classe "principale" pour les objets qui sont par la suite "dessinables", comme ça l'échange avec la classe CDessin s'en trouve plus simple, enfin c'ets comme ça que je PREFERE travailler, ce n'est pas la meilleure je le conçois
    Ou dû moins, a mon niveau (qui n'est pas forcement très élevé je le conçois), je ne sais utiliser que des classes pour faire ça (Et puis ça me convient )
    Parce que j'ai corrigé à l'arrache, et juste changé l'intérieur de la boucle et non la boucle elle même
    Je n'ai jamais utilisé Qt, c'est simplement mon prof d’algorithme en DUT qui nous avait appris à coder comme ceci, et c'est resté. Moi je trouve ça lisible, après ce code n'a pas pour vocation à être publié/lu par d'autres personnes, donc je code "à ma façon", après si c'était un code collaboratif l'utilisation de namespaces ou autre aurait été plus judicieuse c'est vrai.
    C'est amusant, je lisais justement un blog cet après midi, qui racontait que l'un des problème avec les développeurs actuelles, c'est qu'ils se remettent pas en question, ne sont pas curieux, se contente d'un "ça me va comme ça"...

    Ok, fais comme tu veux

    Alors là non, je suis pas d'accord du tout, je préfère LARGEMENT des noms en français, ça fait un peu "newbie", mais c'est tellement plus clair . . .
    (J'aurais pu mettre CooX à la limite)
    Ce n'est pas uniquement pour se la péter que l'on utilise habituellement des mots anglais. On sait jamais comment le code va évoluer et utiliser des termes français bloque dès le départ l'évolution du code (et c'est souvent que ce l'on évite de faire en programmation moderne)
    Et le fait de travailler pour soi ne justifie pas que l'on n'apprenne pas les bonnes méthodes

    Pour "CooX", sérieusement, on te donne une variable comme ça, tu penses tout de suite à "coordonnée x" ?

    Où alors j'ai mal compris ?, ce qui est tout à fait possible vu mon niveau pas très élevé

    Bref, que je fasse .clear(), .erase(), ou même une boucle de pop_back(), toujours CE résultat, le end_of_storage est tout pourri.
    La cause de mon problème je pense, j'ai donc essayé de resize le vecteur, mais comme c'est une fonction que j'ai jamais utilisé, je vais voir ça sur la doc, je tente, et je vous dis quoi
    Puisque tu donnes le lien vers la document de vector, maintenant, il te reste à cliquer dessus et à lire...
    Regarde la différence entre la mémoire utilisée size() et la mémoire réservée capacity(), en particulier la fonction reserve()Bon courage

  14. #14
    Invité
    Invité(e)
    Par défaut
    Juste au passage, je conseillerais d'utiliser memcheck ou une alternative pour tester tes memory leaks.

    C't'un peu plus exhaustif si tu veux voir tes probs d'alloc/dealloc

    Pour "CooX", sérieusement, tu penses tout de suite à "coordonnée x" ?
    . Allez disons courtney pour rester dans le bon ton.

    Ce n'est pas uniquement pour se la péter que l'on utilise habituellement des mots anglais
    c'est aussi pour copier le code plus facilement.

  15. #15
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,
    Citation Envoyé par Soporythmique Voir le message
    Je n'ai jamais utilisé Qt, c'est simplement mon prof d’algorithme en DUT qui nous avait appris à coder comme ceci, et c'est resté. Moi je trouve ça lisible, après ce code n'a pas pour vocation à être publié/lu par d'autres personnes, donc je code "à ma façon", après si c'était un code collaboratif l'utilisation de namespaces ou autre aurait été plus judicieuse c'est vrai.
    Heuu, juste une petite question...

    A partir de quand estimes tu que ton code devient collaboratif

    Ne crois tu pas qu'il serait "logique", à partir du moment où tu exposes du code ici, d'estimer que ceux qui voudront essayer de t'aider aient le droit de comprendre facilement ton code

    N'est-ce pas, d'une certaine manière, déjà du travail collaboratif

    Faut il te rappeler que tous les intervenants sur ce forum interviennent à titre strictement gracieux et bénévole, et que, partant de là, ils peuvent tous estimer que leur temps n'est ni plus ni moins précieux que le tien

    Ne crois tu pas que le fait de rendre ton code intelligible et facilement compréhensible puisse éviter à tout ce beau monde de perdre un temps précieux (à leurs yeux) à essayer de le comprendre, et que, en aidant leur compréhension, tu les aides à t'aider et donc que tu t'aides toi même

    Où alors j'ai mal compris ?, ce qui est tout à fait possible vu mon niveau pas très élevé
    Tu le dis toi même, tu n'as, semble-t-il, pas un niveau excellent en C++...

    Mais, quelle que soit l'école dont tu sors, surtout si on t'a farci la tête avec l'idée que tu étais le meilleur, ne crois tu pas qu'il est peut etre temps de te remettre en question lorsque des intervenants dont l'expérience est prouvée par le nombre de leurs réponses et par leur points te font des remarques

    Tu viens nous demander de l'aide et les gens prennent sur leur propre temps pour essayer de te l'apporter.

    La moindre des choses est, peut etre, de prendre leurs différentes remarques en compte, tu ne crois pas
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Problème pour vider une ListBox
    Par djames37 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 07/08/2011, 19h13
  2. Problème pour vider une combobox multicolonne
    Par kgb1917 dans le forum Windows Forms
    Réponses: 11
    Dernier message: 31/01/2010, 23h58
  3. [C# 2.0] Problème pour vider une imagelist
    Par mikyfpc dans le forum Windows Forms
    Réponses: 11
    Dernier message: 18/05/2009, 19h07
  4. [C] Problème pour vider un buffer clavier
    Par mickael777 dans le forum Windows
    Réponses: 7
    Dernier message: 08/11/2007, 17h05
  5. problème pour vider un formulaire
    Par jomannix dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 26/06/2007, 15h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo