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 :

Libérer un tableau de double avec un pointeur sur classe abstraite


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Février 2013
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 92
    Points : 49
    Points
    49
    Par défaut Libérer un tableau de double avec un pointeur sur classe abstraite
    Bonjour à toutes et à tous,

    Comment faire pour libérer la mémoire d'un tableau de double qui est dans une classe dérivée d'une classe abstraite 'Base' et instanciée suivant cette dernière ? Par exemple:

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    Class Animal {
    protected :
    public :
        virtual int GetPoils() = 0;
    };
     
    Class Chat:public Animal{
      public: 
        int GetPoils() { return toto[0];}
        Chat(){
            toto = (double *) malloc(2 * sizeof(double));
            toto[0] = 1.0; 
            toto[1] = 2.0;
        }
        ~Chat(free(toto));
      private:
        double * toto;
     
    };
     
    Class Simulation {
      private:
        Animal * mon_animal;
     
      public:
        int main(void){
          mon_animal = &Chat();
        }
    };
    Ici, le destructeur de Chat() est bien appelé mais le free(toto) génère un dump core. Si je supprime free(toto); pas de problème, mais je suppose que je génère une fuite mémoire (toto n'étant pas désalloué). Je suppose que c'est lié au fait que Simulation détruit le pointeur 'mon_animal' dans la foulée.

    Bien sur il existe la solution d'utiliser un std::vector mais si on se réfère à ce problème en particulier, il faudrait que j'appelle le destructeur de la classe dérivée avant qu'il ne soit appelé par défaut lors de la destruction de la classe l'utilisant (provoquant alors une fuite mémoire) ? je ne suis pas sur de comprendre l'origine du problème.

    Merci pour votre aide!

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    1. En C++, ne jamais utiliser malloc - realloc free (ou seulement en cas de force majeur, justement parce que, par exemple, realloc n'existe pas en C++)
    2. En C++, il faut utiliser le couple new delete. Je te laisse chercher mais il y a 2 delete et cette question revient souvent dans les tests pour noobs des recruteurs
    3. En C++, le destructeur peut être virtuel. Je te laisse chercher

  3. #3
    Membre du Club
    Inscrit en
    Février 2013
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 92
    Points : 49
    Points
    49
    Par défaut
    1. Bien recu!
    2. Pour l'instant je ne vois pas (je vais creuser, probablement un delete de mon_animal (après un new *) et un delete de toto?)
    3. Il suffirait d'écrire virtual ~Animal{free(toto)}; dans la classe abstraite après avoir mis toto comme membre de Animal? Mais comment faire pour les classes dérivées qui ne possède pas toto en membre? La vérité doit être ailleurs Mulder...

    Je ne cherche pas à me faire recruter (ou en tout cas je doute d'être débauché par des boites info! ).

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Grasshoper Voir le message
    2. Pour l'instant je ne vois pas
    delete[]


    Citation Envoyé par Grasshoper Voir le message
    Mais comment faire pour les classes dérivées qui ne possède pas toto en membre? La vérité doit être ailleurs Mulder...
    Je ne comprends pas le truc
    Si à un moment tu as mis un membre dans une classe, toutes les classes dérivées vont l'avoir, même en héritage privé.

    Et justement le destructeur virtuel permet d'appeler les destructeurs dans le sens inverse des constructeurs, et non pas seulement le destructeur de la classe mère.
    Dans un autre sens, il faut bien qu'il y ait ce système, sinon tu ne pourrais jamais ajouter de pointeurs dans les classes dérivées

  5. #5
    Membre du Club
    Inscrit en
    Février 2013
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 92
    Points : 49
    Points
    49
    Par défaut
    J'essaye de comprendre: sur l'exemple que je donne le free(toto) me fait un core dump. Je constate que le bon destructeur est appelé (celui de la classe fille donc) mais pourquoi est-ce que ca ne marche pas?
    Commet tu le suggères il doit me manquait un delete quelque part, le delete[] est celui de free(toto) et l'autre devrait être un delete mon_Animal ?

    Bien sur je suis d'accord avec ce que tu dis: le fait que les classes dérivées vont aussi avoir le membre de la classe mère, mais dans mon exemple je pensais plutôt à une autre classe Oiseau::Animal() qui ne posséderait pas le membre toto.

  6. #6
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    mon_animal = &Chat(); je crois que tu tiens pas loin de la palme du pointeur le plus daubé au monde. Un problème sur le free toto est un moindre mal à ce stade.
    Où donc as-tu vu cette syntaxe pour avoir un pointeur de chat dans un animal ? Et tu peux jeter cette source dans la foulée.

    Bien sur il existe la solution d'utiliser un std::vector mais si on se réfère à ce problème en particulier, il faudrait que j'appelle le destructeur de la classe dérivée avant qu'il ne soit appelé par défaut lors de la destruction de la classe l'utilisant (provoquant alors une fuite mémoire) ? je ne suis pas sur de comprendre l'origine du problème.
    Qu'est-ce donc que ce charabia ?
    Ton problème a quoi de particulier au juste ?
    vector sert aux collections, malloc devrait resté au C, et la première chose à savoir quand on espère faire de l'héritage c'est virtual.
    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.

  7. #7
    Membre du Club
    Inscrit en
    Février 2013
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 92
    Points : 49
    Points
    49
    Par défaut
    Merci pour ton retour et tes commentaires, pour la syntaxe je me suis inspiré de:
    http://www.cplusplus.com/doc/tutorial/polymorphism/

    J'ai bien une classe abstraite et ai donc remplacé ce pointeur maudit par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      public:
        int main(void){
          mon_animal = new Chat();
        }
    mais ici c'est le destructeur de la classe de base Animal() qui est appelé, donc je ne libère pas toto().
    Edit: Ok j'ai pigé le destructeur peut être virtuel! merci

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Je te réponds sur le delete puisque tu n'as pas réagi

    En C++, si tu veux créer 1 seul objet de type XXX, tu vas utiliser le couple new delete.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    XXX* one_XXX = new XXX(/*params*/);
    // or XXX* one_XXX = new XXX; - default constructor
     
    // ...
     
    delete one_XXX;
    Par contre si tu veux 1 tableau d'objets de type XXX, tu vas utiliser le couple new delete[].
    Exemple avec un tableau de 16 éléments :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    XXX* one_XXX = new XXX[16];
     
    // ...
     
    delete[] one_XXX;

  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
    Pourquoi utiliser new et delete quand on peut utiliser vector et unique_ptr?
    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 du Club
    Inscrit en
    Février 2013
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 92
    Points : 49
    Points
    49
    Par défaut
    Ok, merci, oui j'avais bien saisit pour le couple new delete[], ce que j'avais mal compris c'est que le destructeur peut être virtuel également,
    maintenant ca fonctionne très bien, c'est juste que l'appel à la vtable est affreusement lent (je fais beaucoup de simulations et grosso modo je prends 43% de temps en plus dans la figure, mais bon il faudra que je teste avec un bon compilateur, je suis sur une vieille charrette à l'heure actuelle).
    merci encore!

  11. #11
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    virtual est un moyen parmi d'autres de faire des l'objet mais pas le seul. CRTP en est un autre. Si les perfs sont un problème il faudrait poster plus de code et définir ton vrai objectif. Perdre 43% de perf en ajoutant une vtable, j'en doute.
    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.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 24/03/2013, 21h08
  2. probleme avec les pointeurs sur des objet heterogene
    Par Fifou625 dans le forum Débuter
    Réponses: 4
    Dernier message: 09/12/2011, 21h27
  3. Réponses: 2
    Dernier message: 30/12/2009, 20h44
  4. Réponses: 2
    Dernier message: 21/03/2007, 10h55
  5. Réponses: 4
    Dernier message: 15/10/2006, 18h05

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