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 :

[C++] allocation dynamique de la mémoire trop importante


Sujet :

C++

  1. #1
    Membre éclairé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2004
    Messages
    477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 477
    Par défaut [C++] allocation dynamique de la mémoire trop importante
    Bonjour,

    J'ai une application qui fait une importante opération et qui prend les 100% de l'UC.

    Durant cette opération la charge dédiée dans le gestionnaire de tâche augmente sans cesse jusqu'à atteindre les 500Mo. Enorme...

    J'ai fait attention à ce que chaque allocation de mémoire avec l'opérateur new soit suivi d'un delete. Mais rien n'y fait je reste à 500Mo. Ce qui me fait peur c'est qu'à la fin de mon opération je reste à 500Mo. Et la aussi je n'arrive pas à faire redescendre la valeur. Il faut que je kill le process pour revenir à la normale.

    Dans le code je fais à chaque fois ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    MonObj * obj = new MonObj()
     
    /*fait appel au destructeur de mon objet qui lui même delete les objets du style TStringList ... */
    delete obj ; 
    obj = NULL;
    Comment faire pour améliorer l'allocation dynamique de la mémoire ?
    Merci

  2. #2
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MonObj * obj = new MonObj()
     
    /*fait appel au destructeur de mon objet qui lui même delete les objets du style TStringList ... */
    delete MonObj; 
    MonObj = NULL;
    Ca compile ça ???? Car MonObj est une classe (et pas une instance) et tu fais MonObj = NULL et delete MonObj.

  3. #3
    Membre éclairé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2004
    Messages
    477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 477
    Par défaut
    Désolé je me suis trompé en écrivant! Je fais biensur un delete sur obj et je remet obj à NULL.

    Je suis un peu fatigué moi LOL!

  4. #4
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Ca ne suffit pas à faire prendre autant de mémoire.


    As-tu des allocations qui sont écrites dans une boucle ?

    Car a priori, c'est plus le comportement d'un programme du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while(true)
      obj = new Objet();
     
    delete obj;
    Normalement, il est possible de détecter ce genre de problème (soit en regardant ton code de plus près), soit avec un utilitaire de détection de fuite mémoire du style : valgrind.

    EDIT : mais si ton code n'est pas très gros, ça va peut être plus vite de voir ça à la main.

  5. #5
    Membre éclairé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2004
    Messages
    477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 477
    Par défaut
    J'ai en effet dans mon code quelques endroits ou je boucle et je fais des allocations dynamiques. Mais j'ai bien regardé, a chaque sortie de boucle je delete.

  6. #6
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Citation Envoyé par Pfeffer
    J'ai en effet dans mon code quelques endroits ou je boucle et je fais des allocations dynamiques. Mais j'ai bien regardé, a chaque sortie de boucle je delete.

    Tu es sûr de sortir de ta boucle. Tu vois que dans l'exemple que je t'ai montré, il y a une fois écrit new pour une fois écrit delete, pourtant, il y a une infinité de new qui sera fait à l'exécution.

  7. #7
    Membre éclairé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2004
    Messages
    477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 477
    Par défaut
    Oui je suis certain que je sors de ma boucle vu que l'application me renvoie un résultat suite à cette opération. Et puis je peux recommencer une nouvelle fois mais la je fais tout sauter LOL vu que la mémoire n'est pas revenue à son état d'origine.

  8. #8
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    . Il faut que je kill le process pour revenir à la normale.
    En tout cas, ça ça veut dire que ton programme ne s'arrête pas de lui même et donc que tu dois avoir une boucle infinie...

  9. #9
    Membre éclairé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2004
    Messages
    477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 477
    Par défaut
    Non je me suis mal exprimé, lorsque je quitte l'application et ceux normalement (sans passer par le gestionnaire de tâche), tout redevient normal!

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Vérifie que tu n'as pas de truc sournois de ce style:
    http://en.wikipedia.org/wiki/Memory_...an.27s_example
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Pourquoi t'utilises tout simplement pas du RAII ?

  12. #12
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par Pfeffer
    Non je me suis mal exprimé, lorsque je quitte l'application et ceux normalement (sans passer par le gestionnaire de tâche), tout redevient normal!
    Normal, l'OS libère la mémoire automatiquement.
    Sinon, tu peux utiliser les pointeurs intelligents au cas où.
    Les conteneurs de la STL ne libèrent pas non plus la mémoire quand on fait un clear.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 641
    Par défaut
    Salut,

    Je serais un peu de l'avis de millie...

    Si tu fais une allocation dynamique dans une boucle, il faut que le delete correspondant se trouve aussi dans une boucle équivalente... le tout, en veillant toujours à ne pas refaire une allocation sur un pointeur qui serait perdu du fait de l'allocation...

    Deux "cas d'école":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    MonObj *obj;
    for(int i=0;i<10;i++)
    {
        obj=new MonObj();
        // nok: on perd toute référence à l'objet alloué lors du passage précédent
        // dans la boucle
        ...
    }
    delete obj;//ne libérera que le dernier obj alloué... et on n'a aucune possibilité
               //récupérer les 9 premiers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    for( int i=0;i<10;i++)
    {
        MonObj *obj;
        obj=new MonObj();
        ...
        delete obj;
        //ok: l'objet est libéré avant d'essayer d'allouer le suivant lors du passage
        //suivant dans la boucle
    }
    Mais ca peut etre plus vicieux que cela...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    class MonObj
    {
        public:
            MonObj* Create();
            MonObj();
            ~MonObj();
            void Mafonct();
            ...
        protected:
            MonObj *Suivant;
    }
     
    MonObj::MonObj():Suivant(NULL)
    {
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    MonObj* MonObj::Create(MonObj* actuel)
    {
        MonObj* nouveau=new MonObj();
        actuel->Suivant=nouveau;
        return nouveau;
    }
    void MonObj::Mafonct()
    {
        MonObj* recup;
        recup=Create();
        this->Suivant=recup;
        for(int i=0;i<10;i++)
        {
            recup=Create(recup);
        }
        //traitement
        delete Suivant;
    }
    pourrait tres bien fonctionner... pour autant (et à la condition sine qua non) que l'implémentation du destructueur soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    MonObj::MonOb()
    {
        delete Suivant;
    }
    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

  14. #14
    Membre émérite
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Par défaut
    Pourquoi n'emplois-tu pas des pointeurs intelligents de la STL ( std::auto_ptr ) ?
    Tu peux aussi employer des containers stl comme vector ou list ( voir ce dont tu as réellement besoin ) et utiliser des pointeurs intelligents de la Boost ( boost::shared_ptr ), afin de pouvoir les mettres dans les containers ?

  15. #15
    Membre éclairé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2004
    Messages
    477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 477
    Par défaut
    J'ai regardé un peu les vector et les container et j'ai encore une petite question.

    Lorsque j'alloue un TStringList et que je fais un delete derrière. Est ce que je supprime tout le container ou seulement la dernière ligne de ma liste ?

    Parce que dans mon cas, j'utilise beaucoup les TStringList pour stocker des chaines de caractères. Mais je peux mettre 5000 lignes par exemple dans ma liste.

    Sinon merci à tous je vais essayer de résoudre cette fuite mémoire avec la classe vector.

  16. #16
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Si tu détruis ton conteneur, tout est désalloué.

Discussions similaires

  1. Allocation de mémoire trop importante[france ioi]
    Par anorexia dans le forum Débuter
    Réponses: 0
    Dernier message: 21/02/2009, 16h17
  2. allocation dynamique de la mémoire
    Par ralf91 dans le forum C#
    Réponses: 4
    Dernier message: 08/04/2008, 18h16
  3. Réponses: 6
    Dernier message: 20/02/2008, 10h24
  4. [VC++/ASM] Allocation dynamique de mémoire ?
    Par Magus (Dave) dans le forum x86 32-bits / 64-bits
    Réponses: 7
    Dernier message: 21/12/2004, 15h05
  5. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31

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