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 :

référence sur variable locale


Sujet :

C++

  1. #1
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut référence sur variable locale
    Bonjour

    je voudrais savoir si c'est dangereux de faire un delete sur un pointeur assigné à NULL?
    Comme dans le cas présent où on fait un delete sur un pointeur dans un destructeur.

    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
    class B{
    	B(){};
    	B(int o):a(o){};
    private:
    	int a;
    };
     
    class A{
    public:
    	A(int o):l(o){
    		n=0;
    	}
    	~A(){
    		delete n;
    	}
    private:
    	B *n;
    	int l;
    };
     
    int main()
    {
     
    	{
    		A a(4);
    	}
    En revanche, y a t il un risque si on fait ceci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class A{
    public:
    	A(int o):l(o){
    		n=0;
    	}
    	~A(){
    		delete n;
    	}
    merci

  2. #2
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Non ça ne fait rien.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

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

    Pour être un peu plus complet: NULL est la seule adresse (en attendant null_ptr de la prochaine norme) connue pour être invalide.

    Delete "sait" donc qu'il n'a rien à faire sur cette adresse

    Il faut cependant faire attention aux indirections qui se rajoutent:

    Tu devra obligatoirement tester l'adresse affectée à ton pointeur si tu essaye de désallouer la mémoire d'un membre de celui-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    A::~A()
    {
        delete ptr->membre1;
    }
    posera effectivement problème si ptr vaut NULL et devra donc prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    A::~A()
    {
        if(ptr)
            delete ptr->membre1;
        /* pour faire bonne mesure :D */
        delete ptr;
    }
    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

  4. #4
    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
    Non, mais la meilleur solution consiste encore à encapsuler ton pointeur dans une classe qui s'en occupe spécifiquement ... un pointeur intelligent quoi !

  5. #5
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    Non, mais la meilleur solution consiste encore à encapsuler ton pointeur dans une classe qui s'en occupe spécifiquement ... un pointeur intelligent quoi !
    Avant de vouloir utiliser des shared pointeur,il faut je pense savoir parfaitement manipuler les pointeurs normaux

  6. #6
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    j'ai une autre question, c'est sur le renvoie par référence d'une variable locale. Je le vois souvent.
    Et il me semble que c'est une très grosse erreur, car comportement indéfini.
    Par exemple:

    int& f(){
    int a=3;
    return a;
    }

    En effet, il se trouve que l'objet a va être détruit, et donc la référence va être un alias d'un objet qui n'existe plus.

    En fait ca ne pose pas de pb pour des build in types, mais pour des objets plus complexes, qui ont entre autre de la mémoire allouée dynamiquement, ca peut poser problème. En fait, il faut éviter a tout pris de renvoyer des build in types, sauf pour l'opérateur = ou il faut renvoyer une référence sur this.
    Vous êtes ok?

  7. #7
    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
    En deux mots: on ne renvoie jamais une référence sur un objet temporaire à la fonction.

    Qu'il s'agisse d'un type défini par l'utilisateur ou d'un type primitif ne change strictement rien: toute variable définie sans avoir recours à l'allocation dynamique dans une fonction sera systématiquement détruite en sortie de fonction.

    Tu ne peux donc envisager de renvoyer une référence que:
    • si tu veux renvoyer un membre d'une classe
    • si tu veux renvoyer l'objet courent (ce qui est pointé par this)
    Dans tous les autres cas, renvoie une valeur, et non une référence
    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

  8. #8
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    si tu veux renvoyer un membre d'une classe
    je comprends l'autre point, mais pas celui-là. Peux tu stp me donner un exemple?
    merci

  9. #9
    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
    Tu peux renvoyer une référence uniquement si l'élément renvoyé existe en dehors de la fonction.

    Soit, tu veux en réalité récupérer l'objet courent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class A
    {
        public:
            A & foo()
            {
                /* ... */
                return *this;
            }
    };
    Soit, tu renvoies un membre de la classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class A
    {
        public:
            Type & foo()
            {
                return t;
            }
        private:
            Type t;
    };
    Si tu n'es pas dans une de ces configurations, tu renvoie une valeur

    [EDIT]Nota: l'idéal, dans la deuxième solution reste toujours de renvoyer une référence constante et de rendre la fonction constante, histoire d'éviter toute modification "extérieure" inopportune
    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

  10. #10
    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
    Salut,
    Citation Envoyé par deubelte Voir le message
    Avant de vouloir utiliser des shared pointeur,il faut je pense savoir parfaitement manipuler les pointeurs normaux
    Une approche pertinente est alors de travailler sur tes propres enveloppes RAII pour la gestion des pointeurs afin d'en comprendre les raisons, les variétés et les choix d'implémentations possibles etc.
    Citation Envoyé par deubelte Voir le message
    En fait ca ne pose pas de pb pour des build in types, mais pour des objets plus complexes, qui ont entre autre de la mémoire allouée dynamiquement, ca peut poser problème. En fait, il faut éviter a tout pris de renvoyer des build in types, sauf pour l'opérateur = ou il faut renvoyer une référence sur this.
    Vous êtes ok?
    Avoir une référence ou un pointeur sur un objet détruit est un comportement indéterminé que l'objet soit un type natif ou un type complexe. Tout simplement car les environnements sont susceptibles de réutiliser l'espace libéré qu'il soit sur la pile ou sur le tas dès qu'il est libéré.

Discussions similaires

  1. Erreur sur variables locales
    Par dergeekpanda dans le forum Administration système
    Réponses: 1
    Dernier message: 16/07/2014, 12h27
  2. [VI-2003] Référence hors page sur fichier local
    Par le_sayan dans le forum Visio
    Réponses: 0
    Dernier message: 09/06/2011, 09h41
  3. Réponses: 6
    Dernier message: 23/03/2010, 13h01
  4. Filtre sur variable locale en version 5.1.9
    Par souris56 dans le forum Deski
    Réponses: 8
    Dernier message: 13/04/2007, 18h01
  5. Problème variable locale sur MATLAB
    Par nuans dans le forum MATLAB
    Réponses: 10
    Dernier message: 12/04/2007, 10h34

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