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 :

portée d'une variable temporaire.


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 65
    Points : 58
    Points
    58
    Par défaut portée d'une variable temporaire.
    Bonjour à tous,

    voici un bout de code que j'ai programmé, il fonctionne mais je ne comprends pas pourquoi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    int CNode::Insert()
    {
      CElmt* pElmt = new CElmtInt(5); // CElmtInt dérive de CElmt qui contient
                                                   // une fonction virtuelle pure 
      Element = pElmt;  // Element est un pointeur sur un CElmt
      return 1;
    }
    Quand la fonction a été lue, que devient le pointeur pElmt ? CE QUE JE CROIS, c'est que c'est une variable temporaire créée dans une fonction, donc sa portée reste la fonction. Autrement dit, la zone pointée doit être détruite à la sortie de la fonction, le destructeur de CElmt devant être appelé.

    Eh bien je me plante, car j'ai testé pour voir si le destructeur de CElmt (ou celui de CElmtInt) est appelé, mais non !!! De plus, en dehors de la fonction, Element pointe sur la même zone mémoire que je viens de créer.

    C'est vraiment bizarre, je viens de créer dans une fonction une variable dont la zone pointée n'est pas détruite en fin de fonction. Quelqu'un pourrait-il m'expliquer ?

    Je vous remercie par avance.

  2. #2
    Membre confirmé Avatar de getz85
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2008
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2008
    Messages : 423
    Points : 462
    Points
    462
    Par défaut
    Bonjour,

    Ce comportement est normal, c'est même l'une des règles de base des pointeurs: à chaque new correspond un delete.

    Dans ton code, la mémoire allouée par la ligne CElmt* pElmt = new CElmtInt(5); n'est pas libérée à la fin de ta fonction. C'est à toi de libérer cette mémoire avec un delete pElmt;.

    Pour l'affectation Element = pElmt; , comme Element est également un pointeur, il va prendre l'adresse mémoire correspondant au pointeur pElmt.
    Vu que tu ne libères pas la mémoire à la fin de ta fonction, il est normal que ce pointeur Element pointe toujours vers cette même zone mémoire.

    Par contre si tu fais un delete pElmt avant la fin de ta fonction, Element sera normalement NULL, puisque les deux pointeurs pointent vers la même adresse mémoire.

    En espérant t'avoir aidé!

  3. #3
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Salut.
    Il ne faut pas confondre « variable » et « donnée pointée ».

    Dans ton exemple, la variable locale « pElmt » est bien détruite à la fin de ta fonction.
    Mais c'est uniquement le pointeur qui est détruit, pas les données qu'il pointait !
    Lorsque l'on fait une allocation dynamique (un « new »), on alloue une zone mémoire qui est censée rester valide même après le retour de la fonction dans laquelle l'allocation a été demandée.

    En gros, « pElmt » est crée sur la pile, alors que les données crées via l'allocation dynamique le sont sur le tas.
    http://c.developpez.com/faq/?page=va...#VARS_tas_pile

    Ensuite, c'est normal que « Element » pointe sur la même zone mémoire.
    Lorsque dans l'avant-dernière ligne de la fonction tu fais l'affectation, tu recopies la valeur de « pElmt » dans « Element ».
    Autrement dit, puisque ce sont des pointeurs, tu recopies l'adresse pointée par « pElmt », et pas les données qui sont crées dynamiquement.
    Comme je le disais, ces données-là doivent rester valides jusqu'à ce que les détruisent explicitement (via « delete »).

    Mais j'ai l'impression que « allocation dynamique » et « pointeur », ça ne te parle pas beaucoup…
    Je me trompe ?

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 65
    Points : 58
    Points
    58
    Par défaut
    si si, j'ai parfaitement compris.

    J'ai juste une question. Dans la fonction main(), les destructeurs sont bien appelés automatiquement à la fin de la fonction, non ? ou bien, c'est pareil, toute zone mémoire allouée dynamiquement subsiste tant que l'opérateur delete ne figure pas explicitement ?

    par exemple, dans le code simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    int main(void)
    {
      double* p = new double;
      *p = 3.5 ;
     
      return 1;
    }
    la zone mémoire que pointe p (donc un double) est-elle détruite ou non à la fin de la fonction ?

    merci pour vos réponses.

  5. #5
    Membre confirmé Avatar de getz85
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2008
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2008
    Messages : 423
    Points : 462
    Points
    462
    Par défaut
    Non, elle n'est pas détruite à la fin du main.Dès que tu as un new, c'est à toi de gérer la libération de la mémoire par un delete, sous peine de provoquer des Memory leak.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 65
    Points : 58
    Points
    58
    Par défaut
    Très bien.

    J'ai compris ces réponses, et vous remercie de me les avoir données.

    ++

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

Discussions similaires

  1. Porté d'une variable
    Par koolkris dans le forum Delphi
    Réponses: 3
    Dernier message: 08/03/2007, 20h29
  2. Portée d'une variable dans une boucle FOR ?
    Par Neo41 dans le forum C++
    Réponses: 20
    Dernier message: 17/11/2006, 11h14
  3. [XSLT] pb portée d'une variable
    Par NPortmann dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 23/05/2006, 15h53
  4. Réponses: 10
    Dernier message: 06/03/2006, 23h22
  5. Portée d'une variable globale
    Par Giill dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 27/12/2005, 10h13

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