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 :

visual C++ point d'arrêt mémoire destructeur


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 120
    Points : 49
    Points
    49
    Par défaut visual C++ point d'arrêt mémoire destructeur
    Bonjour

    Dans mon programme je place des breakpoints pour vérifier des valeurs, voir si certaines fonctions s'éxécutent , etc...

    Seulement, il m'arrive d'arrêter par SHIFT+F5 le débuggeur.

    Or les destructeurs des classes ne sont jamais appelées. Est-ce normal ?
    Comme j'ai des pointeurs un peu partout, je me demande si interrompre ainsi le programme ne fait pas perdre de la mémoire.

    Bien sûr je n'utilise pas partout des pointeurs intelligents. D'ailleurs est-ce qu'en utilisant des pointeurs intelligents, je passerai dans les destructeurs ?

    Merci pour vos réponses.

  2. #2
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Si tu utilises des variables automatiques, il n'y a pas de raison que ça ne passe pas par le constructeur. Si tu utilises des pointeurs, n'oublie pas le delete.

    Pour les pointeurs intelligents, je ne connais pas assez pour en parler.

    Pour la fuite mémoire, en théorie ça devrait effectivement bloquer une partie de la mémoire. Mais il me semble que quand on lance le programme, l'OS lui réserve une plage mémoire, qu'il libère ensuite quand le programme s'arrête, et que ça devrait donc annuler la perte de mémoire ; mais là je n'en suis pas certain, il faudrait quelqu'un qui s'y connait mieux au niveau architecture OS/hardware pour confirmer ou infirmer.

  3. #3
    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
    Question bête: Tes destructeurs sont virtuels?

  4. #4
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    l'utilisation des pointeurs intelligents peut effectivement t'assurer que le destructeur sera bien appelé.

    Cela dit, sous visual, quand tu interromp l'execution (shift+F5), le programme ne va pas être fermé proprement. Il va simplement vider la mémoire comme un bourrin. Autrement dit, il n'appelera pas tes destructeurs (ni aucune autre partie de ton code d'ailleurs).

    Sinon, comme il a été dit plus haut, si tu n'utilises pas systématiquement des pointeurs intelligent: un new => un (et un seul) delete.

    Et enfin, il est toujours bon de le rappeller: en c++, on utilise des pointeurs quand on ne peut pas faire autrement. Aujourd'hui, je n'utilise quasiment plus de pointeurs dans mon code. Et quand je suis obligé, de plus en plus rarement, j'utilise des pointeurs intelligents (perso, j'ai opté pour ceux de boost).
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  5. #5
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 120
    Points : 49
    Points
    49
    Par défaut
    Merci pour vos réponses qui me posent plus de questions.

    Variables automatiques ? je ne sais pas ce que c'est.

    J'ai besoin de pointeurs car je crée certaines instances de classes qui n'ont pas raison de durer trop longtemps.

    Je vais m'inspirer du tutorial sur les pointeurs intelligents qui vient de paraître. En utilisant Boost aussi.

    Mes destructeurs sont bien en virtuels.

    Cela dit, sous visual, quand tu interromp l'execution (shift+F5), le programme ne va pas être fermé proprement. Il va simplement vider la mémoire comme un bourrin. Autrement dit, il n'appelera pas tes destructeurs (ni aucune autre partie de ton code d'ailleurs).
    Donc même avec des pointeurs intelligents il ne passera pas dans les destructeurs si je quitte comme un bourrin. Faut que je teste.

  6. #6
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par MABB Voir le message
    J'ai besoin de pointeurs car je crée certaines instances de classes qui n'ont pas raison de durer trop longtemps.
    Je ne vois pas le rapport. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MonObjet {
    //... code de MonObjet
    };
     
    main(){
       {
          MonObjet o; // creation de o, une instance de MonObjet
       } // destruction de o car on sort de sa portée.
    }
    Difficile de "faire durer moins longtemps" un objet (une ligne. Bien que dans la vraie vie, cette instance ne sera certainement jamais construit car le compilo voit qu'il ne sert à rien) et pourtant ce n'est pas un pointeur. Enfin je crois que je n'ai pas compris ce que tu voulais dire.

    Citation Envoyé par MABB Voir le message
    Je vais m'inspirer du tutorial sur les pointeurs intelligents qui vient de paraître. En utilisant Boost aussi.
    Excellente initiative

    Citation Envoyé par MABB Voir le message
    Donc même avec des pointeurs intelligents il ne passera pas dans les destructeurs si je quitte comme un bourrin.
    Effectivement.

    Citation Envoyé par MABB Voir le message
    Faut que je teste.
    Excellente initiative
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  7. #7
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Citation Envoyé par MABB Voir le message
    Variables automatiques ? je ne sais pas ce que c'est.
    C'est simplement comme ça qu'on appelle les variables "ordinaires", créées sur la pile, par opposition à celles créées dynamiquement avec pointeur/allocation mémoire. Elles sont crées dans un bloc, et sont automatiquement détruites à la sortie du bloc.

    Citation Envoyé par MABB Voir le message
    J'ai besoin de pointeurs car je crée certaines instances de classes qui n'ont pas raison de durer trop longtemps.
    Justement, si une variable ne doit durer que l'espace d'un bloc, autant utiliser simplement une variable automatique, l'intérêt des pointeurs et de l'allocation dynamique est justement de permettre à une variable d'exister jusqu'à ce qu'elle soit explicitement détruite par le programmeur.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    #include <string>
    using namespace std;
     
    string f1()
    {
        string s("f1"); // Variable automatique détruite à la fin de la fonction
        return s; // C'est une copie qui est renvoyée, la variable elle même est détruite
    }
     
    string& f2()
    {
        string s("f2"); // Variable automatique détruite à la fin de la fonction
        return s; // Un excellent moyen de se faire beaucoup de mal, puisqu'on renvoie une référence sur une variable qui n'existera plus
    	// Note : VS fait un warning
    }
     
    string* f3()
    {
        string* s = new string("f3"); // Une variable dynamique, qui survivra à sa fonction créatrice
        return s; // On renvoie l'adresse
    }
     
     
    int main()
    {
        string str("main"); // Variable automatique détruite à la fin du main
     
        {
            string str2("bloc"); // variable automatique, détruite à la fin du bloc
        }
     
        if(1 == 1)
        {
            string str2("if"); // variable automatique, détruite à la fin du if
        }
     
        string * pstr = 0; // Toujours initialiser à null
     
        str = f1(); // Tout va bien
        str = "change1"; // Idem
     
        str = f2(); // Devrait marcher, copie de la variable renvoyée, avant sa destruction
        str = "change2"; // Tout va bien
     
        pstr = &f1(); // Attention les dégâts, récupération de la copie temporaire
        (*pstr) = "change3"; // Vous êtes mort
     
        pstr = &f2(); // Attention les dégâts, récupération d'une variable en sursis
        (*pstr) = "change4"; // Badaboom
     
        pstr = f3(); // Ok!
        (*pstr) = "change4"; // Toujours bon
     
        delete pstr; // Ne pas oublier !!
     
        return 0;
    }
    Ce code compile, mais attention à l'exécution

  8. #8
    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
    Points : 4 625
    Points
    4 625
    Par défaut
    string * pstr = 0; // Toujours initialiser à null
    Mauvaise idée, mieux vaut toujours initialiser à une vraie valeur plutôt qu'à une valeur nulle.

    delete pstr; // Ne pas oublier !!
    Mauvaise idée.
    Un delete ne devrait apparaître que dans un destructeur. Le code donné n'est d'ailleurs pas du tout exception-safe, i.e. il va y avoir des fuites quand une exception sera levée.
    Boost ftw

  9. #9
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    C'est un code très très très mauvais, le but ici était plutôt d'exposer les différences entre variable automatique, variable instanciée dynamiquement, et leur durées de vie, ainsi que les problèmes qui sont susceptibles d'apparaître selon ce que l'on utilise.

  10. #10
    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
    Aucun destructeur n'est appelé quand on tue un processus.

    De plus, la norme n'oblige pas non plus à appeler les destructeurs en cas d'exception C++ non-gérée: La fonction terminate() est appelée, c'est tout ce qu'elle demande.
    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.

Discussions similaires

  1. points d'arrêt workflow ds visual studio
    Par medchafik dans le forum SharePoint
    Réponses: 3
    Dernier message: 04/05/2010, 23h04
  2. [visual studio 2003] Point d'arrêt dans un ascx
    Par trihanhcie dans le forum ASP.NET
    Réponses: 9
    Dernier message: 05/09/2007, 08h32
  3. [Plugi][phpeclipse] point d'arrêt pas pris en compte
    Par damjal dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 22/11/2005, 23h58
  4. [vb.NET][xmlTextReader] influence d'1 point d'arrêt
    Par Rom_1 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 25/07/2005, 11h06
  5. possible de sauvegarder ses points d'arrêts ?
    Par Merfolk dans le forum C++Builder
    Réponses: 2
    Dernier message: 14/09/2004, 11h23

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