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 :

Question sur delete


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut Question sur delete
    Yo!

    J'ai une question qui peut paraître bête, mais bon...
    J'ai le code suivant:

    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
    IIterator< UneClasse* > *  buildIter = 0;
    //Ok, on instancie sur la stack un pointeur null
     
    switch (blablabla)
    {
     case 1:
    buildIter=fonc1(...);
    break;
     case 2:
    buildIter=fonc2(...);
    break;
     case 3:
    buildIter=fonc3(...);
    break;
    default:
    ....
    }
     
    delete buildIter ;
    buildIter = 0 ;
    On voit ici l'utilisation de delete sur buildIter, mais buildIter n'a pas été instancié sur le tas avec new. Je croyais qu'il fallait utiliser delete quand on instancie un truc sur le tas.

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    que font fonc1, fonc2, ... ?
    probablement un new.
    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.

  3. #3
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    Exact, ca marche si on fait :



    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
    std::list<int>& fussnc(std::list<int> *dfsdf)
    {
     
    std::list<int>* temporaire=new std::list<int>();
     
    return (*temporaire);
    }
     
    int main()
    {  
     
    	 std::list<int> *fsdf=0;
         fussnc(fsdf);
    	 delete fsdf;
     
    }
    Dans le cas présent, pas de memory leak. En fait, j'ai tendance à penser que new et delete doivent se faire dans le même scope

  4. #4
    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
    Bonjour

    On critique souvent la mauvaise utilisation des pointeurs... et j'ai l'impression que c'est le cas ici.
    - pointeur nu, c'est moche (ton code n'est pas du tout exception free)
    - pourquoi un pointeur tout court ?
    - pourquoi créer l'objet dans un fonction et pas directement (et passer une référence donc)
    - avant de faire le new, il faut vérifier que le pointer n'est pas nul (fuite mémoire potentielle)
    - respect de la "règle" : "celui qui créé, c'est celui qui détruit" ?
    - il n'y aura pas de différence de coût entre copier un pointeur sur un itérateur ou copier un itérateur (ou faire un swap d'un conteneur)
    - pourquoi la fonction fussnc() retourne la liste qui est passé aussi en entrée ?

    Bref, c'est à mon sens du code typique à bannir :
    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
    UnContainer<UneClasse*> c;
    IIterator<UneClasse*> buildIter = c.end();
    //Ok, on instancie sur la stack un pointeur null
     
    switch (blablabla)
    {
        case 1:
            buildIter=fonc1(...);
            break;
        case 2:
            buildIter=fonc2(...);
            break;
        case 3:
            buildIter=fonc3(...);
            break;
        default:
            ....
    }
    // on a fini 
    IIterator< UneClasse*>  buildIter = c.end();
    (c'est mieux avec l'indentation)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void fussnc(std::list<int>& dfsdf)
    {
        // on utilise la liste
    }
     
    int main()
    {  
        std::list<int> fsdf;
        fussnc(fsdf);
    }

  5. #5
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par deubelte Voir le message
    Dans le cas présent, pas de memory leak.
    euh... comment peux-tu affirmer ça ?!

    je t'affirmerai même le contraire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    std::list<int>& fussnc(std::list<int> *dfsdf)
    {
    std::list<int>* temporaire=new std::list<int>();
    return (*temporaire);
    }
    int main()
    {
         std::list<int> *fsdf=0;
         fussnc(fsdf);
         delete fsdf; 
    }
    > le pointeur en paramètre n'est pas utilisé
    > le pointeur créé avec new et retourné n'est pas assigné
    > tu delete un objet NULL
    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.

  6. #6
    Membre éprouvé Avatar de Xtrem_Voyageur
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2009
    Messages : 85
    Par défaut
    On voit ici l'utilisation de delete sur buildIter, mais buildIter n'a pas été instancié sur le tas avec new. Je croyais qu'il fallait utiliser delete quand on instancie un truc sur le tas.
    A priori, cette phrase indique tu es dans le flou.

    Reprenons avec un exemple simple où je vais initialiser tout de suite mon pointeur à null pour être dans la même situation que toi.

    Ici je crée un objet de type pointeur pi sur un entier sur la pile et l'initialise à null.
    pi est donc destiné à recevoir l'addresse d'un entier qui pourra être aussi bien être crée sur la pile ou sur le tas.
    Je crée un entier a sur la pile et je fais pointeur pi dessus. Ici, aussi bien mon entier a que mon pointeur d'entier
    pi sont créés sur la pile, il n'y a donc aucun delete à faire. Les 2 objets seront détruits automatiquement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int a = 11; 
    pi = &a
    Maintenant je crée un entier sur le tas, ce qui se fait avec l'opérateur new, on parle d'allocation mémoire dynamique.
    Et je fais pointer pi sur cette mémoire
    Ici il te faudra faire un delete pi pour libérer la mémoire allouée
    pour placer l'entier 99 et non pas détruire le pointeur pi qui a été crée sur la pile et l'est toujours.
    En faisant cela, je libère donc la mémoire réservée pour contenir l'entier 99 et c'est tout!

    Désolé si je me méprends, mais j'ai l'impression en te lisant que tu penses q'un delete p supprime p, or cela libère la mémoire pointée par p. Le pointeur lui même continue à exister après et sera supprimé automatiquement s'il a été crée sur la pile ou à l'aide d'un delete s'il a lui même été crée sur le tas. En espérant ne pas t'avoir embrouiller.

  7. #7
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    Merci pour vos réponses. Je vais essayer de répondre à certaines d'abord.


    - pointeur nu, c'est moche (ton code n'est pas du tout exception free)
    c'est quoi un pointeur nu?

    - pourquoi un pointeur tout court ?
    que veux tu dire par pointeur tout court?

    - pourquoi créer l'objet dans un fonction et pas directement (et passer une référence donc)
    Parce que c'est ce qui se passe dans le code de la fonction avec les switch.


    - respect de la "règle" : "celui qui créé, c'est celui qui détruit" ?
    Je suis ok. Mais dans le cas de mon premier poste, ce n'était pas le cas. Le code du premier poste ne vient pas de moi (celui avec les switch).

    Bref, c'est à mon sens du code typique à bannir :
    Ouais, ben c'est du code qui existe dans un logiciel d'une grande boite.


    ---------------------------------

    le pointeur en paramètre n'est pas utilisé
    et alors? bon, c'est vrai, c'est pas top.

    le pointeur créé avec new et retourné n'est pas assigné
    exact. C'est là qu'est la fuite de mémoire. Je suis allé un peu trop vite.

    tu delete un objet NULL
    Ceci est autorisé par la norme du C++.


    Je pense que ceci est mieux:

    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
     
    std::list<int>* fussnc(void)
    {
     
    std::list<int>* temporaire=new std::list<int>();
     
    return (temporaire);
    }
     
    int main()
    {  
         Fil2 * zff=new Fil2(1,5);
         union DATATYPE Values = { zff };   // iValue = 10
    	 std::list<int> *fsdf=0;
         fsdf = fussnc();
    	 delete fsdf;
     
    }





    Désolé si je me méprends, mais j'ai l'impression en te lisant que tu penses q'un delete p supprime p, or cela libère la mémoire pointée par p. Le pointeur lui même continue à exister après et sera supprimé automatiquement s'il a été crée sur la pile ou à l'aide d'un delete s'il a lui même été crée sur le tas. En espérant ne pas t'avoir embrouiller.
    Je suis d'accord, mais je vois en quoi consiste la libération de la mémoire pointée par p. Par contre, je vois pas trop ce que signifie "supprimer une variable". Si tu libère la mémoire pointée par un pointeur, alors le pointeur pointe dans le vide. C'est pour cette raison qu'on fait builditer=0 pour pas avoir ce phénomène.

Discussions similaires

  1. question sur new et delete
    Par yann458 dans le forum C++
    Réponses: 15
    Dernier message: 09/08/2014, 19h52
  2. Question sur delete.
    Par pconrad dans le forum Administration
    Réponses: 6
    Dernier message: 24/03/2009, 14h00
  3. Question sur l'éternel delete de Java :-)
    Par threshold dans le forum Entrée/Sortie
    Réponses: 10
    Dernier message: 02/01/2008, 17h42
  4. Question sur les tables inserted et deleted
    Par critok dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 27/06/2006, 22h03
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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