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

Langage C++ Discussion :

Fuite de mémoire dans les appels imbriqués ?


Sujet :

Langage C++

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Janvier 2007
    Messages : 29
    Points : 17
    Points
    17
    Par défaut Fuite de mémoire dans les appels imbriqués ?
    Bonjour à tous,

    Je suis face à un problème que je ne parviens pas à résoudre.
    Soit la ligne suivante, où up et tangage sont des vecteurs (au sens géométrique, pas au sens de structure de stockage) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
          tangage->add(up->times(0.1));
    La fonction add(Vecteur*) ajoute l'argument à son receveur, et la fonction times(double) renvoie le receveur multiplié par le scalaire passé en argument.

    La méthode times(double) crée un nouveau Vecteur, il y a donc un toto=new Vecteur(blabla), et lui donne comme coordonnées les valeurs qui vont bien.
    Est-ce que cet appel à new Vecteur(blabla) est à l'origine d'une fuite de mémoire ?

    Je me pose la question car je ne vois pas à quel moment le resultat de up->times(0.1) sera détruit.

    Si il y a effectuvement une fuite de mémoire, comment faut-il faire ?
    Il faut avouer que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Vecteur* toto = up->times(0.1);
    tangage->add(toto);
    delete toto;
    est un peu lourd, et encore, il n'y a qu'un niveau d'imbrication.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ça dépend si add() "prend possession" du vecteur pointé ou non (ou s'il y a possibilité de récupérer le pointeur par la suite).
    • Si oui, il n'y a pas de fuite.
    • Si non, il y a fuite: Cela peut peut-être être résolu en utilisant des pointeurs intelligents (par exemple, faire retourner un pointeur intelligent par times()).
    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.

  3. #3
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Janvier 2007
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    Merci pour ces précisions. J'ignorais jusqu'à l'existence des pointeurs intelligents.

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Ceci dit, si les données du vecteur sont copiables, pourquoi ne pas utiliser les conteneurs de la STL, sans allocation dynamique de la mémoire de ta main

    Tu modifie ton code pour que up->times() renvoie une référence constante sur le conteneur, et pour que add prenne... une référence constante vers le conteneur en tant qu'argument, "et le tour est joué"

    Mieux, encore, tu n'expose pas une fonction times qui renvoie l'ensemble du vecteur, mais deux fonction (timeBegin() et timeEnd() ) qui renvoie... un itérateur constant, respectivement sur le début et sur l'itérateur qui suit le dernier élément de ton conteneur, et tu modifie la add en conséquence sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    retour LeTypeDeTangage::add(timeIterator & begin, timeIterator & end)
    {
        /* ajout de la plage allant entre begin et end au membre */
    }
    qui sera appelée sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tangage->add(uptime->timeBegin(1.0),uptime->timeEnd(1.0));
    (le tout, avec un typedef définissant timeIterator comme... l'itérateur adequat)
    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

  5. #5
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Koala, l'auteur du post original a pourtant bien précisé que c'était des vecteurs au sens mathématique du terme et non au sens conteneur

    Je dirais que t'es un peu HS

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Effectivement, du moins, pour la deuxième partie de la réponse...

    Cependant, je reste convaincu que le fait de passer par des pointeurs vers des Vecteurs reste une erreur monumentale :p
    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

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Linschn Voir le message
    Merci pour ces précisions. J'ignorais jusqu'à l'existence des pointeurs intelligents.
    Salut,
    Un peu de lecture alors :
    Présentation des pointeurs intelligents en C++ par Loïc Joly
    Gérer ses ressources de manière robuste en C++ par Aurélien Regat-Barrel
    Boost.SmartPtr : Les pointeurs intelligents de Boost par Matthieu Brucher

  8. #8
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Janvier 2007
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    Merci pour les liens. J'étais tombé sur les deux premiers en cherchant ce que sont les pointeurs intelligents.

    Il y a toujours quelque chose que je me demande. Si la méthode times(double) (qui ne modifie pas son receveur) crée un nouvel objet avec new, et le renvoie cette fois-ci par référence, celui ci sera-t-il détruit proprement à la fin du bloc si :


    Mon utilisation forcenée des pointeurs vient du fait que je n'ai fait qu'une fois du C++, et je croyais connaitre le langage, mais j'ai surtout fait du C...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il y a forcément l'un de ces codes qui est mauvais:
    • Si add() prend possession du pointeur pour le détruire avec delete lors de la destruction de la liste, le premier code tentera de deleter un objet sur la pile lors de la destruction de la liste --> Aie!
    • Si add() ne prend pas possession du pointeur, alors le pointeur retourné par times() sera sans doute "perdu" dans une fuite de mémoire, à moins qu'on ne le détruise explicitement (genre, s'il est possible de faire delete titi[index]).


    Il faut plus de contexte pour dire si quelque chose est une fuite ou non, car il n'y a pas réellement de fuite tant qu'il existe un pointeur accessible sur les données...
    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.

  10. #10
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Janvier 2007
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    Il s'agit de vecteurs géométriques, mais peu importe, j'aurais dû prendre autre chose pour mon exemple.

    Si add() ne prend pas possession du pointeur, alors le pointeur retourné par times() sera sans doute "perdu" dans une fuite de mémoire, à moins qu'on ne le détruise explicitement (genre, s'il est possible de faire delete titi[index]).
    times() renvoie une référence, est-ce qu'il faut quand même détruire l'instance ?

    Ce que je pense c'est que quand on le stocke dans une variable, elle est détruite à la fin du bloc, donc tout va bien, et quand on le file directement, il est détruit avec la pile, donc tout va bien aussi, mais je tiens à en être sûr, et la présence d'un new dans la fonction times() me fait penser que je me plante peut-être.

    Dans le cas où je me plante, comment peut-on imbriquer deux fonctions sans fuite de mémoire ? Les pointeurs intelligents sont-ils la seule solution (en sont-ils une) ?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Poste le code de times, sinon on ne va pas s'en sortir.

    Et vite, ou tu devras attendre une heure et demie pour la réponse (transports).
    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.

  12. #12
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Janvier 2007
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    En fait pour l'instant, times() renvoie un pointeur, comme j'aurais fait en C :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Vecteur* Vecteur::times(double scalaire)
    {
      Vecteur* answer=new Vecteur((this->X)*scalaire,(this->Y)*scalaire,(this->Z)*scalaire);
      return answer;
    }
    mais cela oblige à des acrobaties dans le code client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      Vecteur* tmp = view->times(0.01);
      derivee->add(tmp);
      delete tmp;
      tmp=NULL;
    En fait, je cherche un moyen de faire ce qui mathématiquement s'écrirait :
    V<- V + a*U
    Avec ma fonction times, qui renvoie le receveur multiplié, sans modifier le receveur, et add, qui modifie le receveur, ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    V->add(U->times(a));
    Sauf que je ne sais pas comment faire pour éviter la fuite de mémoire : times() est obligé de renvoyer un nouvel objet, je ne vois pas d'autre moyen de le détruire que de passer par un pointeur intelligent, ce qui me semble être l'artillerie lourde pour écraser une mouche, mais je me trompe peut-être.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Vecteur ne m'a pas l'air d'être un gros objet.
    Pour moi, c'est typpiquement le genre de truc que tu devrais gérer entièrement par valeur, surtout que ça a une sémantique de valeur...
    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.

  14. #14
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Effectivement, ça en a tout l'air.
    F.A.Q. : Quand est-ce qu'une classe a une sémantique de valeur ?

  15. #15
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Janvier 2007
    Messages : 29
    Points : 17
    Points
    17
    Par défaut
    Merci beaucoup !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fuite de mémoire dans la SDL ?
    Par Dliw0 dans le forum SDL
    Réponses: 3
    Dernier message: 02/06/2013, 19h21
  2. Fuite de mémoire dans OpenCV
    Par Pg043 dans le forum OpenCV
    Réponses: 1
    Dernier message: 16/01/2009, 12h27
  3. Fuite de mémoire dans "gtk_widget_show" ?
    Par Ekinoks dans le forum GTK+ avec C & C++
    Réponses: 5
    Dernier message: 18/06/2008, 12h00
  4. Fuite de mémoire dans ce code ?
    Par ipingu dans le forum C++
    Réponses: 2
    Dernier message: 07/09/2007, 11h54
  5. Réponses: 8
    Dernier message: 09/02/2007, 15h31

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