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

SL & STL C++ Discussion :

for_each et delete..


Sujet :

SL & STL C++

  1. #1
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut for_each et delete..
    Bonsoir,

    J'aimerais utiliser une boucle for_each pour supprimer les éléments d'un conteneur avant de supprimer ce conteneur mais le delete dans le for_each, il n'aime pas trop... lol

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    vector<champ*> champs;
     
    vector<champ*>::iterator it = champs.begin();
    vector<champ*>::iterator it_end = champs.end();
     
    for_each(it, it_end, delete);
    Erreur de syntaxe, de parenthèse... enfin il doit manquer un truc, j'ai essayé avec delete it ou des trucs de ce genre, mais ca passe pas... c'est possible vous pensez ? ou je parcours avec un for tout simplement...

    Merci
    ++

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Il faut passer soit par un foncteur soit pas une fonction. Mais tu ne peux pas faire comme ca directement car delete n'est pas une fonction, or c'est ce qu'attend for_each. Avec les expressions lamba en C++0X, ca serra beaucoup plus léger à écrire
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    delete n'est pas callable...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void champDeleter(champ* ptr)
    {
       delete ptr;
    }
    ...
     
       foreach(it, it_end, champDeleter);
     
    ...

  4. #4
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut
    D'accord donc pas trop d'intéret d'utiliser un for_each pour supprimer des objets, puisque qu'il faut passer par une "surcouche" pour appeler le delete...

    autant faire un simple for :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for(it, it != it_end ; it++)
        delete it;
    ??

    Merci
    Bonne soirée

  5. #5
    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
    Par défaut
    Tu es conscient qu'un tel code ne sera pas exception-safe et peut avoir des fuites mémoires ?

  6. #6
    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
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Tu es conscient qu'un tel code ne sera pas exception-safe et peut avoir des fuites mémoires ?
    ++
    Déjà tu devrais partir d'un vector<shared_ptr<champ> >. Ca se passera beaucoup mieux!

  7. #7
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Mais sinon, il y a toujours checked_delete qui est fait pour ça

  8. #8
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut
    Bonjour,

    Que veut dire exactement exception-safe ? Que ca peut entrainer des fuites mémoires ?

    Sinon, ben je suis ici pour apprendre de bonnes pratiques donc oui je suis ouvert à tout ce que vous pouvez dire...
    Par contre, donc, il faudrait que j'installe la bibliothèque BOOST pour utiliser checked_delete et shared_ptr.. ?

    Et donc sans ces bibliothèques, il n'est pas possible de faire un code "robuste" avec les pointeurs ?

    Si déjà avant de faire un delete, je vérifie que ce n'est pas NULL, c'est déjà mieux non ? lol

    Bref, je suis attentif à vos avis

    Merci
    ++

  9. #9
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Tu es conscient qu'un tel code ne sera pas exception-safe et peut avoir des fuites mémoires ?
    Ben pourquoi ?

    Le code proposée par italiasky et celui préconisé par la faq fait strictement la même chose non?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for(it = container.begin(), it != container.end() ; it++)
        delete (*it);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // FAQ
    struct Delete 
    { 
       template <class T> void operator ()(T*& p) const 
       { 
          delete p;
          p = NULL;
       } 
    }; 
     
    ...
       std::for_each(container.begin(), container.end(), Delete()); 
    ...

  10. #10
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut
    Re,

    ouais enfin moi j'avais oublié le (* ) ce qui est complètement différent du coup...

    Mais pour le code de la FAQ, j'arrive pas bien voir un truc...

    Etant donné que c'est un vector de pointeurs, l'it pointe sur chaque cellule du vector et le Delete() s'applique sur le it et non sur le (*it) non ?
    Ca va pas du coup ?
    Ou alors, au Delete, ce n'est pas l'it qui est transmis ?

    Bref, si quelqu'un pourrait m'expliquer comment fonctionne ce code de la FAQ avec le foncteur...

    En gros, je ne comprends pas très bien cette ligne je crois bien : le (T*& p) ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <class T> void operator ()(T*& p) const
    Merci
    ++

  11. #11
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par italiasky Voir le message
    ouais enfin moi j'avais oublié le (* ) ce qui est complètement différent du coup...
    J'avais pas vu.
    Citation Envoyé par italiasky Voir le message
    Etant donné que c'est un vector de pointeurs, l'it pointe sur chaque cellule du vector et le Delete() s'applique sur le it et non sur le (*it) non ?
    Non.
    Si tu regardes dans les sources de la stl, tu verras que for_each fait quelque chose dans ce gout là :
    (Func etant le foncteur que l'on passe en troisième paramètre du for_each):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (; it != it_end; ++it)
    {
          Func(*it); // pour un vector<Object*> on a (*it) = Object*
    }
    (Mais en plus compliqué, avec plein de template partout )

    Pour le foncteur de la FAQ, sa version non template serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct Delete 
    { 
       void operator ()(Object* & p) const 
       { 
          delete p; 
          p = NULL;
       } 
    };
    Bon ceci dit, pour ma part je n'utilise que des vecteurs d'objet ou des vecteurs de shared_ptr<Object>, justement pour éviter ces problèmes assez coton de gestion de la mémoire.

  12. #12
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Bon ceci dit, pour ma part je n'utilise que des vecteurs d'objet ou des vecteurs de shared_ptr<Object>, justement pour éviter ces problèmes assez coton de gestion de la mémoire.
    Oui je crois que c'est ce que je vais faire...
    Vu que là je ne peux pas trop installer de bibliothèques en plus, je vais partir sur un vecteur d'objets tout simplement...
    Ca me simplifiera les choses et beaucoup moins de risque d'avoir une fuite mémoire...

    Petite question tout de même, pas besoin de supprimer les objets d'un vector du coup ? C'est fait automatiquement si on fait un erase ou si le vector est détruit c'est ca ?

    Bonne fin d'aprem
    ++

  13. #13
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par italiasky Voir le message
    Petite question tout de même, pas besoin de supprimer les objets d'un vector du coup ? C'est fait automatiquement si on fait un erase ou si le vector est détruit c'est ca ?
    C'est ça.
    En fait vector.erase(it) appelle le destructeur de (*it).

    Et pour faire un peu de préventive, je te conseille fortement de lire et relire cet item de la FAQ : Comment supprimer correctement des éléments d'un conteneur ?. il m'a sauvé la mise plus d'une fois celui-là!

  14. #14
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Ou sinon, vous ne réinvetez pas la roue et vous utillisez soit checked_delete soit un ptr_container, tous deux étant dans Boost (http://www.boost.org/) bien sûr

  15. #15
    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
    Par défaut
    Citation Envoyé par italiasky Voir le message
    Que veut dire exactement exception-safe ?
    Ça veut dire que ton code, fasse à des exceptions, peut ne pas se comporter correctement.
    Il y a plusieurs niveaux d'exception safety, de la pire à la mieux :
    - Aucune garantie n'est faite quand une exception est levée, le système est laissé en l'état.
    - Une garantie minimale, aucune fuite de resource dont mémoire, mais on peut briser les invariants ce qui peut produire des bugs plus tard
    - Une garantie basique, les invariants sont préservés
    - Garantie rollback, si l'opération échoue, le système est remis dans le même état qu'avant l'opération.

    Avec un conteneur de pointeurs, typiquement, tu n'as aucune garantie.
    Avec le RAII, tu as toujours au moins la garantie basique. Par ailleurs, du code qui ne fournit pas la garantie basique est du code à jeter.


    Citation Envoyé par Arzar
    Ben pourquoi ?

    Le code proposée par italiasky et celui préconisé par la faq fait strictement la même chose non?
    La boucle qui fait des delete ne lève a priori pas d'exception, le problème se situe ailleurs.
    Son code laisse à supposer qu'il fait quelque chose comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    vector<champ*> champs;
     
    for(...)
        champs.push_back(new champ);
     
    foreach(champ* c, champs)
        delete c;
    Ce qui bien entendu n'est pas exception-safe, car aussi bien l'allocation mémoire, que la construction de champ, que l'insertion dans le conteneur peuvent lever des exceptions, et que dans ce cas-là les éléments qui ont déja été insérés ne seront pas libérés.

  16. #16
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 501
    Par défaut
    Ok merci pour toutes ces infos, donc oui il faut vraiment faire gaffe quoi lol

    Merci
    Bonne journée

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

Discussions similaires

  1. Delete on cascade avec SQL server
    Par fadoua dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 14/01/2004, 11h02
  2. delete en cascade
    Par bruno270579 dans le forum Requêtes
    Réponses: 8
    Dernier message: 16/12/2003, 17h17
  3. fonction postgresql qui delete un enr
    Par access dans le forum Requêtes
    Réponses: 1
    Dernier message: 16/11/2003, 14h44
  4. [requête] DELETE + SELECT
    Par doohan dans le forum Requêtes
    Réponses: 6
    Dernier message: 07/07/2003, 12h27
  5. [langage] delete de fichier
    Par lolive dans le forum Langage
    Réponses: 2
    Dernier message: 24/04/2003, 15h04

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