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 :

Map et fuite mémoire


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 149
    Par défaut Map et fuite mémoire
    Bonjour à toutes et à tous,

    reprenant un code j'essaie d'en supprimer les fuites mémoires. Cependant je suis actuellement sur une partie dont je n'arrive pas à me dépatouiller.

    Une Map est utilisée pour stocker des pointeurs de n'importe quoi (on y stocke aussi bien des pointeurs vers des entiers que des pointeurs vers des Vectors, ect).

    Code c++ : 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
    20
    21
    22
    23
    #include <iostream>
    #include <map>
     
    using namespace std;
     
    class BenchEnvironment {
    private:
      static BenchEnvironment* pInstance;
     
     public:
      virtual ~BenchEnvironment();
     
      static BenchEnvironment* getInstance();
     
      void addData(std::string key, void* p_dataToAdd);
      void* getData(std::string key);
     
     private:  
      BenchEnvironment();
     
     private:
      std::map<std::string, void*> datas;   
    };
    Code c++ : 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include "BenchEnvironment.h"
     
    BenchEnvironment *BenchEnvironment::pInstance = NULL;
     
    BenchEnvironment::BenchEnvironment()
    {
    }
     
    BenchEnvironment::~BenchEnvironment()
    {
    	pInstance = NULL;
    }
     
    BenchEnvironment *BenchEnvironment::getInstance()
    {
    	if (pInstance == NULL) {
    		pInstance = new BenchEnvironment();
    	}
    	return pInstance;
    }
     
    void BenchEnvironment::addData(string key, void *p_dataToAdd)
    {
    	datas[key] = p_dataToAdd;
    }
     
    void *BenchEnvironment::getData(std::string key)
    {
    	return datas.find(key)->second;
    }

    Utilisant la class de cette manière :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int test = 1;
    BenchEnvironment::getInstance()->addData("test", &test);

    Cela m'ajoute 3 allocations mais aucune désallocation selon Valgrind.
    Est-ce parce que c'est du void* qu'il ne sait pas comment aller libérer la mémoire des pointeurs ?

  2. #2
    Membre Expert
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 149
    Par défaut
    Avec un delete c'est toujours mieux en fait. T_T
    Perdu dans la taille du code je n'avais pas fait attention à cela.
    Il y a des jours où un café me ferrai pas de mal malgré le fait que je le digère pas...

  3. #3
    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
    Oui, mais ...

    Un delete sur void* compile ???

    Citation Envoyé par N3376 5.3.5.3
    if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.
    Note 78 : This implies that an object cannot be deleted using a pointer of type void* because void is not an object type.
    Il faut donc (sauf erreur de ma part) faire un cast vers le type, soit avoir une hiérarchie d'objet avec destructeur virtuel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class A { virtual ~A() {} };
    class B : public A {};
     
    void delete(void* p) {
       if (p.type() == "int") {
           int* pInt = static_cast<int*>(p)
           delete pInt;
       } else if (p.type() == "A" || p.type() == "") {
           A* pA = static_cast<A*>(p)
           delete pA;
       }
    }
    Plus généralement, utiliser un void* est très très très très moche
    Au pire, utilise boost.any ou boost.variant, mais vérifie quand même si tu n'as pas un problème de conception

    Et utiliser les pointeurs intelligents permet d'éviter d'oublier les delete (et est plus exception safe). Par contre, pas sur que ça passe sur un void*

  4. #4
    Membre Expert
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 149
    Par défaut
    boost n'est pas une bibliothèque disponible de base.
    De plus mes contraintes techniques m'empêcheront de toute manière de l'utiliser. Je joue la taille de mon application à l'octet près en raison d'une cible embarquée très très peu véloce et qui contient peu de mémoire.

    Sinon cela ne lui pose aucun problème au compilateur (testé avec GCC et DIAB).
    J'effectue actuellement le delete sur l'objet BenchEnvironment (qui est la seule allocation dynamique).
    Mes variables sont statiques et donc la mémoire est libérée sans souci.

    Sinon je reste dibutatif.
    J'ai travaillé hier avec les static_cast pour autre chose et j'ai pu observer qu'il effectuait une copie lors de l'utilisation de static_cast.
    Donc du coup il fait une copie castée, et delete le void *, puis delete le int *. Donc on revient à une surcouche pour faire la même chose puisqu'on a toujours le delete du void *.

    A moins que ce sur quoi je travaillais soit un cas spécial :
    char *pChar = static_cast< char * >(maString.c_str());

  5. #5
    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
    Pour le cast, oui, tu créés forcement une copie. Quand tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    float f = 12.34;
    int i = static_cast<int>(f);
    Tu crées une nouvelle variable (i) et il y a bien une copie du temporaire retourné par le cast.
    Pour les pointeurs, idem, tu le copies, mais pas l'objet pointé. Il ne devrait pas y avoir d'appelle à delete sur le void* (implicite) puis sur le int* (explicite)

    Et pour moi, un delete sur void* devrait échouer, le compilateur ne sait pas le type pointé et devrait donc ne pas savoir la taille de l'objet en mémoire à supprimer

    Pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *pChar = static_cast< char * >(maString.c_str());
    c'est quoi cette idée de faire un cast de const char* vers char* pour faire un delete ? (si j'ai bien compris ce que tu fais)
    c_str() créé a priori une copie de ta chaîne en ajoutant un \0 puis tu fais un delete dessus, c'est quoi l'intérêt.
    Et string est déjà une mise en oeuvre du RAII, pas besoin de se préoccuper de supprimer les données

    Bref, j'ai un peu de mal à comprendre...

  6. #6
    Membre Expert
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 149
    Par défaut
    Pas d’inquiétudes la variable char* est belle est bien utilisée avant le delete !

    Le programme utilise des string, jusque là pas de souci.
    Mais dans une message queue on fait passer que du char* donc vient de là ce cast.

    Et string est déjà une mise en oeuvre du RAII, pas besoin de se préoccuper de supprimer les données
    On est tout à fait d'accord là dessus, seule une string * mérite ce traitement.

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

Discussions similaires

  1. Fuite mémoire - Map/Vector
    Par Theri dans le forum Langage
    Réponses: 9
    Dernier message: 25/11/2011, 18h42
  2. [tomcat][memoire] java.net.URL et fuite mémoire
    Par Seiya dans le forum Tomcat et TomEE
    Réponses: 6
    Dernier message: 09/03/2009, 10h41
  3. Outil de recherche de fuite mémoire
    Par eag35 dans le forum MFC
    Réponses: 4
    Dernier message: 02/02/2005, 12h46
  4. [SWT]SWT et fuite mémoire(ou pas)
    Par menuge dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 22/06/2004, 21h40
  5. [debug] fuites mémoires
    Par tmonjalo dans le forum C
    Réponses: 3
    Dernier message: 28/07/2003, 17h20

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