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 :

Delete de listes cr�es par l'allocation du compilateur


Sujet :

C++

  1. #1
    Membre extr�mement actif
    Profil pro
    D�veloppeur informatique
    Inscrit en
    D�cembre 2008
    Messages
    1 022
    D�tails du profil
    Informations personnelles :
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : D�cembre 2008
    Messages : 1 022
    Par d�faut Delete de listes cr�es par l'allocation du compilateur
    Bonjour;

    J'essai de cleaner un programme que je r�utilise
    Fait par deux entreprises Une CMM4 l'autre CMM5.
    Cependant je trouve des scories que je ne r�soud pas.
    Quand je passe dans le destructeur, le compilateur g�n�re le code de destruction des objets d�clar�s au niveau de l'objet sur lequel pointe le destructeur.
    Je met l'exemple du code initial � disposition pour comprendre: voila la partie D�claration de l'objet. Il y a donc deux listes de cr�e et le compilateur � l'appel du destructeur va g�n�rer un code qui d�truira les listes. et il se plante dans la detruction de la deuxi�me liste

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class CNgramer
    {
      private:
        enum enCNramerMethod
        {
          SEARCH_NGRAMS =1,
          DELETE_NGRAMS,
        };
        std::list<std::wstring> wsListTrim1;
        std::list<std::wstring> wsListTrim2;
    Je pr�cise que j'ai supprim� l'appel du programme pour ce test et qu'on est dans un cycle constructeur destructeur sans autre code appel� et donc on peut juger que les donn�es n'ont pas �t� perverties par d'autres codes.
    J'ai donc cod� un destructeur qui d�truit explicitement les deux listes et ce code qui marche parfaitement sur la premi�re se plante comme la pr�c�dente sur la deuxi�me
    il y a sept termes dans la 1� liste et deux dans la deuxi�me liste

    voici le code du 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
    CNgramer::~CNgramer()
    {
       std::list<std::wstring>::iterator it;
       it = wsListTrim1.begin();
       while( it != wsListTrim1.end())
       {
          std::wstring *pStr;
          pStr = &(std::wstring)*it;
          delete pStr;
          it++;
       }
       delete &wsListTrim1;
       it = wsListTrim2.begin();
       while( it != wsListTrim2.end())
       {
          std::wstring *pStr;
          pStr = &(std::wstring)*it;
          delete pStr;
          it++;
       }
       wsListTrim2.clear();
       delete &wsListTrim2;
    }
    Puis je d�duire que la destruction r�ussie des donn�es de la deuxi�me liste exclue une perversion dans ces donn�es ou dois-je chercher dans cette direction?

  2. #2
    Membre extr�mement actif
    Profil pro
    D�veloppeur informatique
    Inscrit en
    D�cembre 2008
    Messages
    1 022
    D�tails du profil
    Informations personnelles :
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : D�cembre 2008
    Messages : 1 022
    Par d�faut Destructeur de liste qui marche
    Bonjour;

    comme souvent en formulant une discussion j'ai fait des essais pour trouver une solution. J'ai donc d�plac� le delete dans le constructeur apr�s utilisation des donn�es et cr�e les donn�es par un new qui donne une donn�e allou� dans la pile (apparemment bien mieux tol�r�e par le compilateur).
    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
    CNgramer::CNgramer()
    {
        CPOS* pPos;
        std::list<std::wstring> *wsListTrim1;
        std::list<std::wstring> *wsListTrim2;
        std::list<std::wstring>::iterator itStringPos;
        pPos = new CPOS();
        m_bOptionProblem = false;
        wsListTrim1 = new std::list<std::wstring>;
        wsListTrim2 = new std::list<std::wstring>;
        COption::GetShortValue(OPTION_SECTION_CNGRAMER, OPTION_KEYNAME_MIN_NGRAM_DEGREE, m_shMinNgramDegreeOM, &m_shMinNgramDegreeOM);
        COption::GetShortValue(OPTION_SECTION_CNGRAMER, OPTION_KEYNAME_MAX_NGRAM_DEGREE, m_shMaxNgramDegreeOM, &m_shMaxNgramDegreeOM);
        COption::GetShortValue(OPTION_SECTION_CNGRAMER, OPTION_KEYNAME_MIN_PERCENTAGE, m_shMinPercentageOM, &m_shMinPercentageOM);
        COption::GetShortValue(OPTION_SECTION_CNGRAMER, OPTION_KEYNAME_MIN_OCCURENCE, m_shMinOccOM, &m_shMinOccOM);
        COption::GetStringList((std::wstring)OPTION_SECTION_CNGRAMER,(std::wstring)OPTION_KEYNAME_LIST_TRIM1  , *wsListTrim1, wsListTrim1);
        COption::GetStringList((std::wstring)OPTION_SECTION_CNGRAMER,(std::wstring)OPTION_KEYNAME_LIST_TRIM2  , *wsListTrim2, wsListTrim2);
        if(m_bOptionProblem == false)
        {
           itStringPos = wsListTrim1->begin();
           while (itStringPos != wsListTrim1->end())
           {
              enPOS Curpos = pPos->CPOS::GetPOSWithPOSLabel(*itStringPos);
              m_ListTrim1.push_back(Curpos);
              itStringPos++;
           }
           itStringPos = wsListTrim2->begin();
           while (itStringPos != wsListTrim2->end())
           {
              m_ListTrim2.push_back(pPos->CPOS::GetPOSWithPOSLabel(*itStringPos));
              itStringPos++;
           }
        }
        std::list<std::wstring>::iterator it;
       it = wsListTrim1->begin();
       while( it != wsListTrim1->end())
       {
          std::wstring *pStr;
          pStr = &(std::wstring)*it;
          delete pStr;
          it++;
       }
       delete wsListTrim1;
       it = wsListTrim2->begin();
       while( it != wsListTrim2->end())
       {
          std::wstring *pStr;
          pStr = &(std::wstring)*it;
          delete pStr;
          it++;
       }
       delete wsListTrim2;
       delete pPos;
    }

  3. #3
    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 JeanNoel53 Voir le message
    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
    CNgramer::~CNgramer()
    {
       std::list<std::wstring>::iterator it;
       it = wsListTrim1.begin();
       while( it != wsListTrim1.end())
       {
          std::wstring *pStr;
          pStr = &(std::wstring)*it;
          delete pStr;
          it++;
       }
       delete &wsListTrim1;
       it = wsListTrim2.begin();
       while( it != wsListTrim2.end())
       {
          std::wstring *pStr;
          pStr = &(std::wstring)*it;
          delete pStr;
          it++;
       }
       wsListTrim2.clear();
       delete &wsListTrim2;
    }
    Oula
    Jamais, jamais, jamais il ne faut faire des choses comme delete &wsListTrim1. Le destructeur d'un objet membre est appell� automatiquement lors de la destruction de l'objet qui le poss�de, si tu l'appeles encore une fois, alors l'objet membre va �tre d�truit deux fois et tout et n'importe quoi peut arriver (par exemple planter sauvagement )

    Si ta classe est r�ellement comme ceci :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class CNgramer
    {
      private:
        enum enCNramerMethod
        {
          SEARCH_NGRAMS =1,
          DELETE_NGRAMS,
        };
        std::list<std::wstring> wsListTrim1;
        std::list<std::wstring> wsListTrim2;
    Alors ton destructeur doit ressembler � �a :
    Ben oui, y en pas ! Le destructeur de std::list est automatiquement appel� lors de la destruction de CNgramer qui va � son tour appeller correctement les destructeurs respectifs de chaque wstring.

    La seule exception, c'est si tu as d�clar� ta classe comme ceci :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class CNgramer
    {
      private:
        enum enCNramerMethod
        {
          SEARCH_NGRAMS =1,
          DELETE_NGRAMS,
        };
        std::list<std::wstring*> wsListTrim1;
        std::list<std::wstring*> wsListTrim2;
    Cette fois-ci wsListTrim1 et wsListTrim2 ne maintiennent pas des wstring, mais des pointeurs vers des wstring, et dans ce cas uniquement il faut d�truire manuellement chaque wstring dans le destructeur, car par d�faut std::list va supprimer les pointeurs, mais pas les objets point�s.
    Dans ce cas on utilise le code la faq et on obtient :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    ~CNgramer()
    {
    std::for_each(wsListTrim1.begin(), wsListTrim1.end(), Delete());
    std::for_each(wsListTrim2.begin(), wsListTrim2.end(), Delete());
    }
    Ou alors � la main :

    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
     
    ~CNgramer()
    {
        typedef std::list<std::wstring*> ::iterator iterator;
     
        for(iterator it = wsListTrim1.begin() ; it != wsListTrim1.end() ; it++)
       {
           delete &(*it);
       }
     
        for(iterator it = wsListTrim2.begin() ; it != wsListTrim2.end() ; it++)
       {
           delete &(*it);
       }
    }
    Edit : Donc � retenir : Si ta classe poss�de des membres qui sont des pointeurs, alors il faut d�truire manuellement les objets point�s dans le destructeur. Par contre si les membres sont directement des objets (sans l'indirection d'un pointeur) alors leur destruction est automatique et il n'y a rien � faire de sp�cial.

  4. #4
    Membre extr�mement actif
    Profil pro
    D�veloppeur informatique
    Inscrit en
    D�cembre 2008
    Messages
    1 022
    D�tails du profil
    Informations personnelles :
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : D�cembre 2008
    Messages : 1 022
    Par d�faut Destruction des �l�ments constitu� par new
    Bonjour et merci

    Je re�ois tes avis et te confirme que ce que tu dis est juste, mais je maintien que BCB est tr�s sensibles aux allocations et supporte mieux les new suivie de delete que les objets g�n�r�s dans la pile et qu'on a un meilleur r�sultat
    - sur les objets listes en les allouant par un new et en les d�truisant apr�s l'utilisation
    - sur les std::wstring en les d�clarant dans une variable globale( sic...!)
    � bient�t et toujours merci � vous, c'est utile d'avoir des gens r�actifs lorsqu'on est en butte � des probl�mes.
    �+

  5. #5
    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 JeanNoel53 Voir le message
    Bonjour et merci

    Je re�ois tes avis et te confirme que ce que tu dis est juste, mais je maintien que BCB est tr�s sensibles aux allocations et supporte mieux les new suivie de delete que les objets g�n�r�s dans la pile et qu'on a un meilleur r�sultat
    - sur les objets listes en les allouant par un new et en les d�truisant apr�s l'utilisation
    - sur les std::wstring en les d�clarant dans une variable globale( sic...!)
    � bient�t et toujours merci � vous, c'est utile d'avoir des gens r�actifs lorsqu'on est en butte � des probl�mes.
    �+
    std::list et std:: (w)string n'ont probablement pas leur objets sur la pile mais bien sur le tas. Quand tu �cris :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    std::string une_chaine = "tutu";
    une_chaine est sur la pile
    mais la cha�ne "tutu" est probablement sur le tas.

  6. #6
    Membre extr�mement actif
    Profil pro
    D�veloppeur informatique
    Inscrit en
    D�cembre 2008
    Messages
    1 022
    D�tails du profil
    Informations personnelles :
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : D�cembre 2008
    Messages : 1 022
    Par d�faut et quand ca plante?
    Bonjour,

    Suite aux derni�res discussions, je suis revenu en arri�re sur tout �a, et j'ai repris simplement le code du constructeur pour d�truire les chaines apr�s leur utilisation.
    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
     
           itStringPos = wsListTrim1.begin();
           while (itStringPos != wsListTrim1.end())
           {
              enPOS Curpos = pPos->CPOS::GetPOSWithPOSLabel(*itStringPos);
              m_ListTrim1.push_back(Curpos);
              std::wstring *pStr;
              pStr = &(std::wstring)*itStringPos;
              delete pStr;
              itStringPos++;
           }
           itStringPos = wsListTrim2.begin();
           while (itStringPos != wsListTrim2.end())
           {
              m_ListTrim2.push_back(pPos->CPOS::GetPOSWithPOSLabel(*itStringPos));
              std::wstring *pStr;
              pStr = &(std::wstring)*itStringPos;
              delete pStr;
              itStringPos++;
           }
    le destructeur est vide
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    CNgramer::~CNgramer()
    {
    }
    et les d�clarations sont en local
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      private:
        enum enCNramerMethod
        {
          SEARCH_NGRAMS =1,
          DELETE_NGRAMS,
        };
        std::list<std::wstring> wsListTrim1;
        std::list<std::wstring> wsListTrim2;
    avec tout �a c'est comme avant l'application se plante sur la destruction de la premi�re liste ( wsListTrim1) avec l'affichage de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    inline void  __stl_delete(void* __p) { ::operator delete(__p); }
    Que puis je faire pour quitter l'application sans �tre agonie d'injures?

  7. #7
    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 JeanNoel53 Voir le message
    Que puis je faire pour quitter l'application sans �tre agonie d'injures?
    Salut,

    Nul besoin d'appeler explicitement delete sur des objets que tu n'as pas explicitement allou�s :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
              pStr = &(std::wstring)*itStringPos;
              delete pStr;
    Est une erreur car
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    std::list<std::wstring> wsListTrim2;
    En se d�truisant, wsListTrim2 appellera les destructeurs de wstring de tous les �l�ments dans la liste.
    Si tu veux supprimer un �l�ment de la liste, utilises std::list::erase ou std::list::remove.

  8. #8
    screetch
    Invit�(e)
    Par d�faut
    la regle est simple :
    si tu utilise new, tu vas devoir appeler delete
    si tu utilise new[] tu vas devoir utiliser delete[]
    si tu utilise malloc tu vas devoir utiliser free
    si tu ne les utilise pas, n'utilise ni delete ni free!!!

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Fermeture fenetre cr�e par code javascript
    Par Kerod dans le forum G�n�ral JavaScript
    R�ponses: 9
    Dernier message: 27/02/2010, 00h04
  2. Valeur par d�faut d'un liste cr��e par c:foreach
    Par karsmy99 dans le forum Servlets/JSP
    R�ponses: 1
    Dernier message: 28/02/2007, 10h13
  3. R�cup�ration d'ne liste envoy� par formulaire
    Par Leviathan_72 dans le forum Langage
    R�ponses: 5
    Dernier message: 24/11/2005, 09h36
  4. Impossible d'acc�der aux tables non cr��es par dbo
    Par Pete dans le forum MS SQL Server
    R�ponses: 4
    Dernier message: 07/10/2005, 14h01
  5. R�ponses: 1
    Dernier message: 28/09/2005, 18h10

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